aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/index.html4
-rw-r--r--src/state.cpp36
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