git: c508393e49fc - stable/14 - lyaml: vendor import lua bindings for libyaml
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 08 Jul 2025 14:32:22 UTC
The branch stable/14 has been updated by bapt: URL: https://cgit.FreeBSD.org/src/commit/?id=c508393e49fc4d18cf40fa439a9e625bde93a68f commit c508393e49fc4d18cf40fa439a9e625bde93a68f Author: Baptiste Daroussin <bapt@FreeBSD.org> AuthorDate: 2025-06-26 07:12:41 +0000 Commit: Baptiste Daroussin <bapt@FreeBSD.org> CommitDate: 2025-07-08 14:29:16 +0000 lyaml: vendor import lua bindings for libyaml (cherry picked from commit 2bc180ef045e5911cce0cea1c2a139cffd2b577a) --- contrib/lyaml/.gitignore | 9 + contrib/lyaml/.luacov | 8 + contrib/lyaml/AUTHORS | 6 + contrib/lyaml/LICENSE | 27 + contrib/lyaml/NEWS.md | 352 ++++++++++++ contrib/lyaml/README.md | 232 ++++++++ contrib/lyaml/build-aux/config.ld.in | 34 ++ contrib/lyaml/build-aux/luke | 672 ++++++++++++++++++++++ contrib/lyaml/doc/index.html | 97 ++++ contrib/lyaml/doc/ldoc.css | 303 ++++++++++ contrib/lyaml/doc/modules/lyaml.explicit.html | 267 +++++++++ contrib/lyaml/doc/modules/lyaml.functional.html | 236 ++++++++ contrib/lyaml/doc/modules/lyaml.html | 224 ++++++++ contrib/lyaml/doc/modules/lyaml.implicit.html | 533 +++++++++++++++++ contrib/lyaml/ext/yaml/emitter.c | 459 +++++++++++++++ contrib/lyaml/ext/yaml/lyaml.h | 161 ++++++ contrib/lyaml/ext/yaml/parser.c | 410 +++++++++++++ contrib/lyaml/ext/yaml/scanner.c | 340 +++++++++++ contrib/lyaml/ext/yaml/yaml.c | 66 +++ contrib/lyaml/lib/lyaml/explicit.lua | 120 ++++ contrib/lyaml/lib/lyaml/functional.lua | 87 +++ contrib/lyaml/lib/lyaml/implicit.lua | 283 +++++++++ contrib/lyaml/lib/lyaml/init.lua | 534 +++++++++++++++++ contrib/lyaml/lukefile | 47 ++ contrib/lyaml/lyaml-6.2.8-1.rockspec | 59 ++ contrib/lyaml/spec/ext_yaml_emitter_spec.yaml | 239 ++++++++ contrib/lyaml/spec/ext_yaml_parser_spec.yaml | 391 +++++++++++++ contrib/lyaml/spec/ext_yaml_scanner_spec.yaml | 380 ++++++++++++ contrib/lyaml/spec/lib_lyaml_functional_spec.yaml | 121 ++++ contrib/lyaml/spec/lib_lyaml_spec.yaml | 343 +++++++++++ contrib/lyaml/spec/spec_helper.lua | 277 +++++++++ libexec/flua/Makefile | 1 + libexec/flua/liblyaml/Makefile | 22 + 33 files changed, 7340 insertions(+) diff --git a/contrib/lyaml/.gitignore b/contrib/lyaml/.gitignore new file mode 100644 index 000000000000..19d7cbb6dd7d --- /dev/null +++ b/contrib/lyaml/.gitignore @@ -0,0 +1,9 @@ +*~ +*.o +*.so +*.src.rock +/ChangeLog +/build-aux/config.ld +/luacov.*.out +/lyaml-*.tar.gz +/TAGS diff --git a/contrib/lyaml/.luacov b/contrib/lyaml/.luacov new file mode 100644 index 000000000000..0aa52d25e0ea --- /dev/null +++ b/contrib/lyaml/.luacov @@ -0,0 +1,8 @@ +modules = { + ['lyaml'] = 'lib/lyaml/init.lua', + ['lyaml.*'] = 'lib', +} + +runreport = true + +tick = true diff --git a/contrib/lyaml/AUTHORS b/contrib/lyaml/AUTHORS new file mode 100644 index 000000000000..1eb673371bf7 --- /dev/null +++ b/contrib/lyaml/AUTHORS @@ -0,0 +1,6 @@ +lyaml is the work of several authors (see git history for +contributors). + +There is an earlier C LibYAML binding + + Copyright Andrew Danforth <acd@weirdness.net> diff --git a/contrib/lyaml/LICENSE b/contrib/lyaml/LICENSE new file mode 100644 index 000000000000..402e64dfec29 --- /dev/null +++ b/contrib/lyaml/LICENSE @@ -0,0 +1,27 @@ +This software comprises files that are copyright their respective +authors (see the AUTHORS file for details), and distributed under +the terms of the MIT license (the same license as Lua itself), +unless noted otherwise in the body of that file. + +==================================================================== +Copyright (C) 2013-2022 Gary V. Vaughan + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, +and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGE- +MENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +==================================================================== diff --git a/contrib/lyaml/NEWS.md b/contrib/lyaml/NEWS.md new file mode 100644 index 000000000000..32611d83671a --- /dev/null +++ b/contrib/lyaml/NEWS.md @@ -0,0 +1,352 @@ +# lyaml NEWS - User visible changes + +## Noteworthy changes in release 6.2.8 (2022-10-22) [stable] + +### Bug fixes + + - `luke` no longer crashes in `std.normalize` require loops + occasionally in Lua 5.4. + + - lyaml emitter no longer leaks at least six bytes for every + map, sequence and scalar emitted. + + +## Noteworthy changes in release 6.2.7 (2020-11-27) [stable] + +### Bug fixes + + - Don't skip YAML entries from mixed key Lua tables. + + +## Noteworthy changes in release 6.2.6 (2020-08-28) [stable] + +### Bug fixes + + - `luke` really propagates `LDFLAGS` to module compilation + commands. + + +## Noteworthy changes in release 6.2.5 (2020-04-15) [stable] + +### Bug fixes + + - `luke` really propagates `YAML_BINDIR`, `YAML_DIR`, + `YAML_INCDIR` and `YAML_LIBDIR` to checksymbol test in lukefile + given the change to `external_dependencies` layout in 6.1.2. + + +## Noteworthy changes in release 6.2.4 (2019-07-20) [stable] + +### Bug fixes + + - `luke` works with upgraded bootstrap luarocks version of + `require`. + + +## Noteworthy changes in release 6.2.3 (2018-09-16) [stable] + +### New Features + + - Initial support for Lua 5.4. + + +## Noteworthy changes in release 6.2.2 (2018-03-28) [stable] + +### Bug fixes + + - Remove spurious dependency on `std.normalize` and `std._debug` + libraries. + + +## Noteworthy changes in release 6.2.1 (2018-02-20) [stable] + +### Bug fixes + + - `spec/spec_helper.lua` now looks in the correct objdir + for object modules built by luke, instead of adding unused + paths from old Autotools objdirs. So now specl is properly + running examples against the not yet installed lyaml objects. + + +## Noteworthy changes in release 6.2 (2017-11-26) [stable] + +### Bug fixes + + - `luke` uses the correct spelling of LIBFLAG to match luarocks now. + + - `luke` no longer throws spurious `cp: file exists` errors. + + - `luke` works on luajit again. + + +## Noteworthy changes in release 6.1.3 (2017-05-29) [stable] + +### Bug fixes + + - `luke` no longer bombs out with a nil concat error. + + +## Noteworthy changes in release 6.1.2 (2017-04-30) [stable] + +### Bug fixes + + - `luke` now propagates `LUA_DIR`, `YAML_INCDIR` and `YAML_LIBDIR` + correctly. + + +## Noteworthy changes in release 6.1.1 (2017-01-22) [stable] + +### New Features + + - Builds and installs with `luke` instead of Autotools. + + +## Noteworthy changes in release 6.1 (2016-10-08) [stable] + +### Bug fixes + + - `lyaml.load` now correctly reads implicit null scalars in a YAML + document as an `lyaml.null` reference, identical to the "~" + shorthand syntax, according to [the specification][nullspec]. + + ```yaml + empty: + canonical: ~ + english: null + ~: null key + ``` + + +## Noteworthy changes in release 6.0 (2015-07-27) [stable] + +### New Features + + - `lyaml.load` now correctly reads a !!bool tagged scalar from a + YAML document, or an implicit bool value, according to + [the specification][boolspec]. + + ```yaml + %TAG ! tag:yaml.org,2002: + --- + truthy: + - !bool Y + - !bool y + - !bool True + - !bool "on" + falsey: + - !bool n + - !bool OFF + - !bool garbage + ``` + + - `lyaml.load` now correctly reads a !!float tagged scalar from a + YAML document, or an implicit float value, according to + [the specification][floatspec]. + + - `lyaml.load` now correctly reads a !!int tagged scalar from a + YAML document, or an implicit integer value, according to + [the specification][intspec]. + + - `lyaml.load` now supports the !!merge key type according to + [the specification][mergespec]. + + ```yaml + - &MERGE { x: 1, y: 2 } + - &OVERRIDE { x: 0, z: 1 } + - + << : [&MERGE, &OVERRIDE] + z: 3 + ``` + + The anchored tables remain in the document too, so this results in + the following Lua table: + + ```lua + { -- START_STREAM + { -- START_DOCUMENT + { x = 1, y = 2 }, -- MERGE + { x = 0, z = 1 }, -- OVERRIDE + { x = 1, y = 2, z = 3}, -- <<< + } -- END_DOCUMENT + } -- END_STREAM + ``` + +### Bug fixes + + - Multi-line strings were previously being dumped using single quotes + which caused the dumped YAML to break. + + For example, { foo = "a\nmultiline\nstring" } would get dumped as: + + ```yaml + foo: 'a + + multiline + + string' + ``` + + Note the extra line-breaks in between each line. This also causes + YAML parsing to fail (since the blank lines didn't have the expected + indentation). + + This patch fixes the dump to use the YAML literal syntax for any + multi-line strings so the same example gets dumped as: + + ```yaml + foo: |- + a + multiline + string + ``` + + - `lyaml.load` now correctly reads the !!null tag in a YAML + document as an `lyaml.null` reference, identical to the "~" + shorthand syntax, according to [the specification][nullspec]. + +### Incompatible Changes + + - `lyaml.load` now takes a table of options as an optional second + argument, not a simple boolean to determine whether all documents + should be returned from the stream. For now, a `true` second + argument will be converted to the modern equivalent: + + ```lua + lyaml.load (document, { all = true }) + ``` + + - `lyaml.dump` now takes a table of options as an optional second + argument, not an initial table of anchors. For now, a second + argument without any new API keys will be converted to the modern + equivalent: + + ```lua + lyaml.dump (t, { anchors = arg2 }) + ``` + +[boolspec]: http://yaml.org/type/bool.html +[floatspec]: http://yaml.org/type/float.html +[intspec]: http://yaml.org/type/int.html +[mergespec]: http://yaml.org/type/merge.html +[nullspec]: http://yaml.org/type/null.html + + +## Noteworthy changes in release 5.1.4 (2015-01-01) [stable] + + - This release is functionally identical to the last. + + +## Noteworthy changes in release 5.1.3 (2015-01-01) [stable] + + - This release is functionally identical to the last. + + +## Noteworthy changes in release 5.1.2 (2014-12-27) [stable] + +### Bugs Fixed + + - No more spurious .travis.yml is out of date warnings during + `luarocks install lyaml`. + + +## Noteworthy changes in release 5.1.1 (2014-12-19) [stable] + +### Bugs Fixed + + - When using `sudo make install` instead of LuaRocks, `lyaml.so` + is now correctly installed to `$luaexecdir`. + + +## Noteworthy changes in release 5.1.0 (2014-12-17) [stable] + +### New Features + + - Lua 5.3.0 compatibility. + + +## Noteworthy changes in release 5 (2014-09-25) [beta] + +### Build + + - Significantly reduced pointer mismatch warnings from modern GNU + compilers. + +### New Features + + - `lyaml.dump` now takes a second argument containing a table of + potential anchor values in `ANCHOR_NAME = { "match", "elements" }` + pairs format. The first time any are matched in the table being + dumped, they are preceded by `&ANCHOR_NAME` in the output YAML + document; subsequent matches are not written out in full, but + shortened to the appropriate `*ANCHOR_NAME` alias. + +### Bugs Fixed + + - `yaml.emitter` no longer emits numbers in SINGLE_QUOTE style by + default. + + - `yaml.emitter ().emit` returns error strings correctly for invalid + STREAM_START encoding, and MAPPING_START, SEQUENCE_START & SCALAR + style fields. + + +## Noteworthy changes in release 4 (2013-09-11) [beta] + +### New Features + + - New yaml.emitter API returns an object with an emit method for + adding events using yaml_*_event_initialize() calls. + + - New yaml.parser API returns a Lua iterator that fetches the next + event using yaml_parser_parse(). + + - New yaml.scanner API returns a Lua iterator that fetches the next + token using yaml_parser_scan(). + + - Beginnings of Specl specs, starting with a reasonably comprehensive + specifications for the new APIs above. + + - C implementation of lyaml.dump has moved to Lua implementation as + yaml.dump. + + - C implementation of lyaml.load has moved to Lua implementation as + yaml.load. + + - The new Lua implementation of lyaml.load () handles multi-document + streams, and returns a table of documents when the new second + argument is `true`. + + +## Noteworthy changes in release 3 (2013-04-27) [beta] + + - This release is functionally identical to the last. + +### New Features + + - lyaml builds are now made against Lua 5.1, Lua 5.2 and luajit 2.0.0 + automatically, with every commit. + + - move to a cleaner, automated release system. + + +## Noteworthy changes in release 2 (2013-03-18) [beta] + + - This release is functionally identical to the last. + + - Use correct MIT license attribution, relicensing build files to match + Andrew Danforth''s MIT licensed lyaml.c too. + + +## Noteworthy changes in release 1 (2013-03-17) [beta] + +### New Features + + - A binding for libYAML, by Andrew Danforth: Updated for Lua 5.1 and + 5.2, and packaged as a luarock. + + - I spun this out of Specl (http://github.com/gvvaughan/specl) so that + other projects may use it, and to simplify the Specl build. + +### Known Issues + + - There's not really any documentation, sorry. Contributions welcome! diff --git a/contrib/lyaml/README.md b/contrib/lyaml/README.md new file mode 100644 index 000000000000..d1e96845ddfa --- /dev/null +++ b/contrib/lyaml/README.md @@ -0,0 +1,232 @@ +LYAML +===== + +Copyright (C) 2013-2022 Gary V. Vaughan + +[](https://mit-license.org) +[](https://github.com/gvvaughan/lyaml/actions) +[](https://codecov.io/github/gvvaughan/lyaml?branch=release-v6.2.8) + +[LibYAML] binding for [Lua], with a fast C implementation +for converting between [%YAML 1.1][yaml11] and [Lua] tables, +and a low-level [YAML] event parser for implementing more +intricate [YAML] document loading. + +Usage +----- + +### High Level API + +These functions quickly convert back and forth between Lua tables +and [%YAML 1.1][yaml11] format strings. + +```lua +local lyaml = require "lyaml" +local t = lyaml.load (YAML-STRING, [OPTS-TABLE]) +local yamlstr = lyaml.dump (LUA-TABLE, [OPTS-TABLE]) +local null = lyaml.null () +``` + +#### `lyaml.load` + +`lyaml.load` accepts a YAML string for parsing. If the YAML string contains +multiple documents, only the first document will be returned by default. To +return multiple documents as a table, set `all = true` in the second +argument OPTS-TABLE. + +```lua +lyaml.load("foo: bar") +--> { foo = "bar" } + +lyaml.load("foo: bar", { all = true }) +--> { { foo = "bar" } } + +multi_doc_yaml = [[ +--- +one +... +--- +two +... +]] + +lyaml.load(multi_doc_yaml) +--> "one" + +lyaml.load(multi_doc_yaml, { all = true }) +--> { "one", "two" } +``` + +You can supply an alternative function for converting implicit plain +scalar values in the `implicit_scalar` field of the OPTS-TABLE argument; +otherwise a default is composed from the functions in the `lyaml.implicit` +module. + +You can also supply an alternative table for coverting explicitly tagged +scalar values in the `explicit_scalar` field of the OPTS-TABLE argument; +otherwise all supported tags are parsed by default using the functions +from the `lyaml.explicit` module. + +#### `lyaml.dump` + +`lyaml.dump` accepts a table of values to dump. Each value in the table +represents a single YAML document. To dump a table of lua values this means +the table must be wrapped in another table (the outer table represents the +YAML documents, the inner table is the single document table to dump). + +```lua +lyaml.dump({ { foo = "bar" } }) +--> --- +--> foo: bar +--> ... + +lyaml.dump({ "one", "two" }) +--> --- one +--> ... +--> --- two +--> ... +``` + +If you need to round-trip load a dumped document, and you used a custom +function for converting implicit scalars, then you should pass that same +function in the `implicit_scalar` field of the OPTS-TABLE argument to +`lyaml.dump` so that it can quote strings that might otherwise be +implicitly converted on reload. + +#### Nil Values + +[Lua] tables treat `nil` valued keys as if they were not there, +where [YAML] explicitly supports `null` values (and keys!). Lyaml +will retain [YAML] `null` values as `lyaml.null ()` by default, +though it is straight forward to wrap the low level APIs to use `nil`, +subject to the usual caveats of how nil values work in [Lua] tables. + + +### Low Level APIs + +```lua +local emitter = require ("yaml").emitter () + +emitter.emit {type = "STREAM_START"} +for _, event in ipairs (event_list) do + emitter.emit (event) +end +str = emitter.emit {type = "STREAM_END"} +``` + +The `yaml.emitter` function returns an emitter object that has a +single emit function, which you call with event tables, the last +`STREAM_END` event returns a string formatted as a [YAML 1.1][yaml11] +document. + +```lua +local iter = require ("yaml").scanner (YAML-STRING) + +for token_table in iter () do + -- process token table +end +``` + +Each time the iterator returned by `scanner` is called, it returns +a table describing the next token of YAML-STRING. See LibYAML's +[yaml.h] for details of the contents and semantics of the various +tokens produced by `yaml_parser_scan`, the underlying call made by +the iterator. + +[LibYAML] implements a fast parser in C using `yaml_parser_scan`, which +is also bound to lyaml, and easier to use than the token API above: + +```lua +local iter = require ("yaml").parser (YAML-STRING) + +for event_table in iter () do + -- process event table +end +``` + +Each time the iterator returned by `parser` is called, it returns +a table describing the next event from the "Parse" process of the +"Parse, Compose, Construct" processing model described in the +[YAML 1.1][yaml11] specification using [LibYAML]. + +Implementing the remaining "Compose" and "Construct" processes in +[Lua] is left as an exercise for the reader -- though, unlike the +high-level API, `lyaml.parser` exposes all details of the input +stream events, such as line and column numbers. + + +Installation +------------ + +There's no need to download an [lyaml] release, or clone the git repo, +unless you want to modify the code. If you use [LuaRocks], you can +use it to install the latest release from its repository: + + luarocks --server=http://rocks.moonscript.org install lyaml + +Or from the rockspec in a release tarball: + + luarocks make lyaml-?-1.rockspec + +To install current git master from [GitHub][lyaml] (for testing): + + luarocks install http://raw.github.com/gvvaughan/lyaml/master/lyaml-git-1.rockspec + +To install without [LuaRocks], clone the sources from the +[repository][lyaml], and then run the following commands: + +```sh +cd lyaml +build-aux/luke LYAML_DIR=LIBYAML-INSTALL-PREFIX +sudo build-aux/luke PREFIX=LYAML-INSTALL-PREFIX install +specl -v1freport spec/*_spec.yaml +``` + +The dependencies are listed in the dependencies entry of the file +[rockspec][L15]. + + +Bug reports and code contributions +---------------------------------- + +This library is maintained by its users. + +Please make bug reports and suggestions as [GitHub Issues][issues]. +Pull requests are especially appreciated. + +But first, please check that your issue has not already been reported by +someone else, and that it is not already fixed by [master][lyaml] in +preparation for the next release (see Installation section above for how +to temporarily install master with [LuaRocks][]). + +There is no strict coding style, but please bear in mind the following +points when proposing changes: + +0. Follow existing code. There are a lot of useful patterns and avoided + traps there. + +1. 3-character indentation using SPACES in Lua sources: It makes rogue + TABs easier to see, and lines up nicely with 'if' and 'end' keywords. + +2. Simple strings are easiest to type using single-quote delimiters, + saving double-quotes for where a string contains apostrophes. + +3. Save horizontal space by only using SPACEs where the parser requires + them. + +4. Use vertical space to separate out compound statements to help the + coverage reports discover untested lines. + +5. Prefer explicit string function calls over object methods, to mitigate + issues with monkey-patching in caller environment. + + +[issues]: http://github.com/gvvaughas/lyaml/issues +[libyaml]: http://pyyaml.org/wiki/LibYAML +[lua]: http://www.lua.org +[luarocks]: http://www.luarocks.org +[lyaml]: http://github.com/gvvaughan/lyaml +[L15]: http://github.com/gvvaughan/lyaml/blob/master/lyaml-git-1.rockspec#L15 +[yaml.h]: http://pyyaml.org/browser/libyaml/branches/stable/include/yaml.h +[yaml]: http://yaml.org +[yaml11]: http://yaml.org/spec/1.1/ diff --git a/contrib/lyaml/build-aux/config.ld.in b/contrib/lyaml/build-aux/config.ld.in new file mode 100644 index 000000000000..0d55b9e94c30 --- /dev/null +++ b/contrib/lyaml/build-aux/config.ld.in @@ -0,0 +1,34 @@ +--[[ + LYAML binding for Lua 5.1, 5.2, 5.3 & 5.4 + Copyright (C) 2013-2022 Gary V. Vaughan +]] + +title = '@package@ @version@ Reference' +project = '@package@ @version@' +description = [[ +# LYAML binding for Lua + +This is a Lua binding for the fast libYAML C library for converting +between `%YAML 1.1` and Lua tables, with a flexible Lua language +API to load and save YAML documents. + +It works with Lua 5.1 (including LuaJIT), 5.2, 5.3 and 5.4. + +## LICENSE + +The code is copyright by its respective authors, and released under the +MIT license (the same license as Lua itself). There is no warranty. +]] + +dir = '../doc' + +file = { + '../lib/lyaml/init.lua', + '../lib/lyaml/explicit.lua', + '../lib/lyaml/functional.lua', + '../lib/lyaml/implicit.lua', +} + +format = 'markdown' +backtick_references = false +sort = false diff --git a/contrib/lyaml/build-aux/luke b/contrib/lyaml/build-aux/luke new file mode 100755 index 000000000000..3d61f784cbca --- /dev/null +++ b/contrib/lyaml/build-aux/luke @@ -0,0 +1,672 @@ +#!/usr/bin/env lua +--[[ minified code follows, see --help text for source location! ]] +local require=function(modname)if package.loaded[modname]==nil then +if type(package.preload[modname])~="function"then +io.stderr:write("module '" .. modname .. "' not found:\n no valid field package.preload['" .. modname .. "']\n") +return nil +end +package.loaded[modname]=package.preload[modname](modname,"package.preload")end +return package.loaded[modname]end +package.preload['luke._base']=function() +local _ENV=require'std.normalize'{}local function fatal(...)local msg=(...)if select('#',...)>1 then +msg=format(...)end +stderr:write('luke: fatal: '..msg..'\n')exit(1)end +return{diagnose=function(predicate,...)if not predicate then +fatal(...)end +end,fatal=fatal,} +end +package.preload['luke.cli']=function() +local _ENV=require'std.normalize'{'luke._base','luke.lukefile','luke.platforms','std.functional',}local function version()print[[ +luke (Luke) 0.2.3 +Written by Gary V. Vaughan <gary@gnu.org>, 2014 + +Copyright (C) 2022, Gary V. Vaughan +Luke comes with ABSOLUTELY NO WARRANTY. +You may redistribute copies of Luke under the terms of the MIT license; +it may be used for any purpose at absolutely no cost, without permission. +See <https://mit-license.org> for details. +]]exit(0)end +local function help()print[[ +Usage: luke [OPTION]... [VAR=VALUE]... [TARGET] + +Use the source, Luke! + + --help print this help, then exit + --version print version number, then exit + --file=FILE use FILE instead of lukefile + --value=NAME print the value of variable NAME + --quiet without any output + --verbose provide more progress output + +Each TARGET can be one of the module table keys from lukefile, or: + + all build all targets in lukefile + install copy all built targets to $PREFIX + +If no TARGET is given, 'all' is implied. + +Report bugs to https://github.com/gvvaughan/luke/issues.]]exit(0)end +local function opterr(...)local msg=(...)if select('#',...)>1 then +msg=format(...)end +msg=gsub(msg,'%.$','')stderr:write('luke: error: '..msg..'.\n')stderr:write("luke: try '"..arg[0].." --help' for help.\n")exit(2)end +local function display(...)return stdout:write(concat{...})end +local function dump(...)local s=concat(map(list(...),str))if len(s)>0 then +gsub(concat(map(list(...),str)),'\n*$','\n'):gsub('(.-)\n',function(line)stderr:write(' DEBUG: '..line..'\n')end)end +end +local function interpolate_to_substitute(s)return(gsub(s,'%$([%w_]+)','@%1@'))end +return{parse_arguments=function(args)local r={clidefs={},valreqs={},fname='lukefile',install={},log=nop,targets={},verbose=nop,write=display,}map(args,function(opt)case(opt,{['--debug']=function()r.log=dump +end,['%-%-file=(.+)']=function(optarg)r.fname=optarg +end,['%-%-value=(.+)']=function(optarg)r.valreqs[#r.valreqs+1]=optarg +end,['--quiet']=function()r.write=nop +end,['--verbose']=function()r.verbose=display +end,['--help']=help,['--version']=version,['([^-][^=]-)=(.+)']=function(name,value)r.clidefs[name]=value +end,function(opt)if match(opt,'^-')~=nil then +opterr("unrecognized option '%s'",opt)end +append(r.targets,opt)end,})end)return r +end,validate_arguments=function(parsed)local luke,err=loadluke(parsed.fname)diagnose(luke~=nil,'bad %s: %s',parsed.fname,err)if isempty(luke.modules or{})then +fatal("no modules table in '%s', nothing to build",parsed.fname)end +local targets=call(function()if isempty(parsed.targets)or contains(parsed.targets,'all')then +return except(flatten(parsed.targets,keys(luke.modules)),'all')end +local r=filter(parsed.targets,function(target)if target~='install'and luke.modules[target]==nil then +fatal("no rule to make target '%s'",target)end +return true +end)assert(len(r)>0,"no build targets specified")return r +end)local install +local build=pluck(targets,luke.modules)if contains(targets,'install')then +install=build or luke.modules +end +luke.modules=build +if isempty(luke.modules)then +luke.external_dependencies=nil +end +luke.substitute=merge(luke.substitute or{},{package=interpolate_to_substitute(luke.package),version=interpolate_to_substitute(luke.version),})luke.variables=merge(luke.variables or{},collect_variables(luke),{LUA_DIR='/usr',LUA_BINDIR='$LUA_DIR/bin',LUA_INCDIR='$LUA_DIR/include/lua$LUAVERSION',LUA_LIBDIR='$LUA_DIR/lib',objdir=platforms[1],package=luke.package,version=luke.version,})return{clidefs=parsed.clidefs,install=install,log=parsed.log,luke=luke,valreqs=parsed.valreqs,verbose=parsed.verbose,write=parsed.write,}end,} +end +package.preload['luke.compile']=function() +local _ENV=require'std.normalize'{'luke._base','luke.environment','std.functional','type.context-manager','type.path',SHELLMETACHARS='[%s%$"]',}local function spawn(env,...)local command=interpolate(env,concat({...},' '))return with(TmpFile(),TmpFile(),function(out,err)local pipe=concat{command,' >',out.filename,' 2>',err.filename,'; printf $?'}return tonumber(slurp(Pipe(pipe))),slurp(File(err.filename)),slurp(File(out.filename))end)end +local function run(L,env,command)L.write(interpolate(env,concat(command,' ')),'\n')local status,err,out=spawn(env,unpack(command))if status~=0 then +if L.write==nop then +stdout:write(concat(command,' ')..'\n')end +stderr:write(err..'\n')end +return status,out,err +end +local function defines(env,deftables)return zip_with(merge({},unpack(deftables)),function(name,value)local fmt=cond({[int(value)==1]='-D%s'},{[match(value,SHELLMETACHARS)~=nil]="-D%s='%s'"},{[true]='-D%s=%s'})return format(fmt,name,value)end)end +local function incdirs(...)return map(flatten(...),function(v)return'-I'..v +end)end +local function libdirs(...)return map(flatten(...),function(v)return'-L'..v +end)end +local function c_module_path(objdir,name)return format('%s/%s.$LIB_EXTENSION',objdir,gsub(name,'%.','/'))end +local function c_source(module,objdir)local path=gsub(module,'%.','/')local src=c_module_path(objdir,path)return src,(gsub('$INST_LIBDIR/'..path,'/[^/]+$',''))end +local function lua_source(module,src)local abspath='$INST_LUADIR/'..gsub(module,'%.','/')if match(src,'/init%.lua$')then +abspath=abspath..'/init'end +abspath=abspath..'.lua'return src,(gsub(abspath,'/[^/]+%.lua$',''))end +local function module_to_path(module,sources,objdir)return dropuntil(sources,function(source)return case(source,{['.*%.[ch]']=bind(c_source,{module,objdir}),['(.*%.[ch])%.in']=bind(c_source,{module,objdir}),['.*%.lua']=bind(lua_source,{module}),['(.*%.lua)%.in']=bind(lua_source,{module}),function(src)fatal("unsupported source type '%s'",src)end,})end)end +return{build_c_module=function(L,env,luke,name)local rules=luke.modules[name]local c_module=c_module_path(luke.variables.objdir,name)local command={'$MAKEDIRS',dirname(c_module)}local status,err,out=spawn(env,unpack(command))if status~=0 then +stdout:write(concat(command,' ')..'\n')stderr:write(err..'\n')exit(status)end +return run(L,env,flatten('$CC $CFLAGS $LIBFLAG $PKGFLAGS $CPPFLAGS',defines(env,except(list(rules.defines,luke.defines),nil)),incdirs(rules.incdirs,luke.incdirs),rules.sources,'-o',c_module,'$LDFLAGS',libdirs(rules.libdirs,luke.libdirs),'$LIBS',rules.libraries,luke.libraries))end,c_modules=function(modules)return filter(keys(modules),function(name)return dropuntil(modules[name].sources,bind(match,{[2]='%.[ch]$'}))end)end,incdirs=incdirs,install_modules=function(L,env,luke,modules)return reduce(keys(modules),0,function(status,name)if status==0 then +local src,dir=module_to_path(name,modules[name].sources,luke.variables.objdir)if not exists(interpolate(env,dir))then +status=run(L,env,{'$MAKEDIRS',dir})end +if status==0 then +status=run(L,env,{'$INSTALL',src,dir..'/'})end +end +return status +end)end,libdirs=libdirs,run_command=run,spawn=spawn,} +end +package.preload['luke.configure']=function() +local _ENV=require'std.normalize'{'luke._base','luke.compile','luke.environment','std.functional','type.context-manager','type.dict',CCPROGS={'cc','gcc','clang'},}local function logspawn(L,env,...)local status,err=spawn(env,...)if status~=0 and err~=''then +L.log(err)end +return status +end +local function checking(L,...)L.verbose('checking ',concat({...},' '),'... ')end +local function found_library(L,x)if x==nil or x==''then +L.verbose'none required'elseif isempty(x)then +L.verbose'not supported'else +L.verbose(x)end +L.verbose'\n'return x +end +local function found_prog(L,x)L.verbose(x and'yes\n'or'no\n')return x +end +local function found_result(L,x)L.verbose(x==0 and'yes\n'or'no\n')return x~=0 and 0 or 1 +end +local function bindirs(...)return map(flatten(...),function(v)return v..':'end)end +local function compile_command(L,env,config,filename)local command=flatten('$CC','-c','$CFLAGS',incdirs(config.incdir),'$CPPFLAGS',filename)L.log(interpolate(env,concat(command,' ')))return unpack(command)end +local function link_command(L,env,config,a_out,source,lib)local command=flatten('$CC','$CFLAGS',incdirs(config.incdir),'$CPPFLAGS','-o',a_out,source,libdirs(config.libdir),'$LDFLAGS',lib,'$libs',CONFIGENV.libs)L.log(interpolate(env,concat(command,' ')))return unpack(command)end +local function check_executable_in_path(L,env,config,prog)local PATH=concat(bindirs(config.bindir))..getenv('PATH')local found=dropuntil(gmatch(PATH,'[^:]+'),function(path)local progpath=path..'/'..prog +return with(File(progpath,'r'),function(h)return h and isfile(h.context)and progpath or nil +end)end)L.log(found and'found '..found or prog..' not found')return found~=nil +end +local function check_header_compile(L,env,config,header,extra_hdrs)return with(CTest(),function(conftest)conftest:write(format('%s\n#include "%s"\n',extra_hdrs,header))return logspawn(L,env,compile_command(L,env,config,conftest.filename))end)end +local function check_struct_member_compile(L,env,config,structname,member,extra_hdrs)return with(CTest(),function(conftest)conftest:write(format([[ +%s +int main () { +static %s aggr; +if (sizeof aggr.%s) + return 0; +return 0; +} +]],extra_hdrs,structname,member))return logspawn(L,env,compile_command(L,env,config,conftest.filename))end)end +local function try_link(L,env,config,lib,symbol)return with(CTest(),TmpFile(),function(conftest,a_out)conftest:write(format([[ +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char %s (); +int main () { +return %s (); +} +]],symbol,symbol))return logspawn(L,env,link_command(L,env,config,a_out.filename,conftest.filename,lib))end)end +local function try_compile(L,env,config,headers)return with(CTest(),TmpFile(),function(conftest,a_out)conftest:write(format([[ +%s +#if !defined %s || %s == -1 +choke me +#endif +int +main() +{ +return 0; +} +]],headers,config.ifdef,config.ifdef))return logspawn(L,env,link_command(L,env,config,a_out.filename,conftest.filename))end)end +local function check_func_decl(L,env,config,fname,extra_hdrs)return with(CTest(),function(conftest)conftest:write(format([[ +%s +int +main() +{ +#ifndef %s +(void) %s; +#endif +return 0; +} +]],extra_hdrs,fname,fname))return logspawn(L,env,compile_command(L,env,config,conftest.filename))end)end +local function check_func_link(L,env,config,fname)return with(CTest(),TmpFile(),function(conftest,a_out)conftest:write(format([[ +/* Define to an innocous variant, in case <limits.h> declares it. + For example, HP-UX 11i <limits,h> declares gettimeofday. */ +#define %s innocuous_%s + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with declaration below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef %s + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char %s (); + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_%s || defined __stub__%s +choke me +#endif + +int main () { +return %s (); +} +]],fname,fname,fname,fname,fname,fname,fname))return logspawn(L,env,link_command(L,env,config,a_out.filename,conftest.filename))end)end +local function add_external_deps(env,config,prefix)if prefix~=nil then +for k,v in next,{bindir='$%s_BINDIR',incdir='$%s_INCDIR',libdir='$%s_LIBDIR'}do +local envvar=interpolate(env,format(v,prefix))if envvar~=''then +config[k]=envvar +end +end +end +end +local function format_includes(includes)return map(includes or{},function(include)return format('#include "%s"',include)end)end +local configure=setmetatable(OrderedDict({checkprog=function(L,env,config)return dropuntil(config.progs,function(prog)checking(L,'for',prog)if found_prog(L,check_executable_in_path(L,env,config,prog))then *** 6606 LINES SKIPPED ***