diff options
-rw-r--r-- | docs/index.html | 4 | ||||
-rw-r--r-- | src/state.cpp | 36 |
2 files changed, 25 insertions, 15 deletions
diff --git a/docs/index.html b/docs/index.html index 79b33f1..dc159f4 100644 --- a/docs/index.html +++ b/docs/index.html | |||
@@ -70,7 +70,7 @@ | |||
70 | </p> | 70 | </p> |
71 | 71 | ||
72 | <p> | 72 | <p> |
73 | This document was revised on 12-Jun-24, and applies to version <tt>4.0.0</tt>. | 73 | This document was revised on 24-Sep-24, and applies to version <tt>4.0.0</tt>. |
74 | </p> | 74 | </p> |
75 | </font> | 75 | </font> |
76 | </center> | 76 | </center> |
@@ -681,6 +681,7 @@ | |||
681 | 681 | ||
682 | <p> | 682 | <p> |
683 | Any non-<tt>nil</tt> value causes initialization of <tt>"base"</tt> and <tt>"jit"</tt> (the latter only for LuaJIT-based builds).<br /> | 683 | Any non-<tt>nil</tt> value causes initialization of <tt>"base"</tt> and <tt>"jit"</tt> (the latter only for LuaJIT-based builds).<br /> |
684 | Trying to load a library not supported by the running Lua flavor will raise an error, unless the library name is postfixed with a <tt>'?'</tt>.<br /> | ||
684 | Initializing the standard libs takes a bit of time at each lane invocation. This is the main reason why "no libraries" is the default. | 685 | Initializing the standard libs takes a bit of time at each lane invocation. This is the main reason why "no libraries" is the default. |
685 | </p> | 686 | </p> |
686 | 687 | ||
@@ -716,6 +717,7 @@ | |||
716 | These tables are built from the modules listed here. <tt>required</tt> must be an array of strings, each one being the name of a module to be required. Each module is required with <tt>require()</tt> before the lanes function is invoked. | 717 | These tables are built from the modules listed here. <tt>required</tt> must be an array of strings, each one being the name of a module to be required. Each module is required with <tt>require()</tt> before the lanes function is invoked. |
717 | So, from the required module's point of view, requiring it manually from inside the lane body or having it required this way doesn't change anything. From the lane body's point of view, the only difference is that a module not creating a global won't be accessible. | 718 | So, from the required module's point of view, requiring it manually from inside the lane body or having it required this way doesn't change anything. From the lane body's point of view, the only difference is that a module not creating a global won't be accessible. |
718 | Therefore, a lane body will also have to require a module manually, but this won't do anything more (see Lua's <tt>require</tt> documentation). <br /> | 719 | Therefore, a lane body will also have to require a module manually, but this won't do anything more (see Lua's <tt>require</tt> documentation). <br /> |
720 | Module names may contain characters matching <tt>std::isalnum(c_) || c_ == '.' || c_ == '-' || c_ == '_'</tt>. Anything else is considered a valid name separator.<br /> | ||
719 | ATTEMPTING TO TRANSFER A FUNCTION REGISTERED BY A MODULE NOT LISTED HERE WILL RAISE AN ERROR. | 721 | ATTEMPTING TO TRANSFER A FUNCTION REGISTERED BY A MODULE NOT LISTED HERE WILL RAISE AN ERROR. |
720 | </td> | 722 | </td> |
721 | </tr> | 723 | </tr> |
diff --git a/src/state.cpp b/src/state.cpp index 322def8..aa6e6a9 100644 --- a/src/state.cpp +++ b/src/state.cpp | |||
@@ -247,21 +247,29 @@ namespace state { | |||
247 | STACK_CHECK(_L, 0); | 247 | STACK_CHECK(_L, 0); |
248 | 248 | ||
249 | // scan all libraries, open them one by one | 249 | // scan all libraries, open them one by one |
250 | if (!_libs.empty()) { | 250 | auto isLibNameChar = [](char const c_) { |
251 | unsigned int _len{ 0 }; | 251 | // '.' can be part of name for "lanes.core" |
252 | for (char const* _p{ _libs.data() }; *_p; _p += _len) { | 252 | return std::isalnum(c_) || c_ == '.' || c_ == '-' || c_ == '_'; |
253 | // skip delimiters ('.' can be part of name for "lanes.core") | 253 | }; |
254 | while (*_p && !std::isalnum(*_p) && *_p != '.') { | 254 | while (!_libs.empty()) { |
255 | ++_p; | 255 | // remove prefix not part of a name |
256 | } | 256 | auto _nameStart{ std::find_if(std::cbegin(_libs), std::cend(_libs), isLibNameChar) }; |
257 | // skip name | 257 | if (_nameStart == _libs.end()) { |
258 | _len = 0; | 258 | break; |
259 | while (std::isalnum(_p[_len]) || _p[_len] == '.') { | 259 | } |
260 | ++_len; | 260 | auto const _prefixLen{ std::distance(_libs.begin(), _nameStart) }; |
261 | } | 261 | |
262 | // open library | 262 | auto const _nameEnd{ std::find_if(_nameStart, std::cend(_libs), [&isLibNameChar](char const _c) { return !isLibNameChar(_c); }) }; |
263 | Open1Lib(_L, { _p, _len }); | 263 | // advance to the end of the character sequence composing the name |
264 | auto const _nameLen{ std::distance(_nameStart, _nameEnd) }; | ||
265 | if (_nameLen == 0) { | ||
266 | break; | ||
264 | } | 267 | } |
268 | // open library | ||
269 | std::string_view const _libName{ _libs.substr(_prefixLen, _nameLen) }; | ||
270 | Open1Lib(_L, _libName); | ||
271 | // advance to next item (can't do this earlier as it invalidates iterators) | ||
272 | _libs.remove_prefix(_prefixLen + _nameLen); | ||
265 | } | 273 | } |
266 | lua_gc(_L, LUA_GCRESTART, 0); | 274 | lua_gc(_L, LUA_GCRESTART, 0); |
267 | 275 | ||