Posted 13 July 2013 - 03:20 PM
Hi!
[I've CC 1.5]
I usually read the built in programs for some inspiration, and I found something I can hardly explain. In the shell, there are local variables like sPath or tEnv declared at the beginning which give the paths to search the programs, or the environment used at this level of shell, and everything goes well, we can access to sPath with shell.path and shell.setPath, and tEnv is well used while running programs, new shells included.
And now, in the bios, before the declaration of os.loadAPI, there is a local table declared to ensure that an API is not loaded twice. But that doesn't work at all! When I call os.loadAPI on the same API twice in the lua prompt, or even twice on a row in the same program, I do not raise the error "API "..sName.." is already being loaded". I'm very curious to know how it works. I haven't yet tried to load twice the same API in the bios, cause I didn't fell like changing it, but I think this could be very informative.
My hypothesis, though I do not convince myself, is that the bios isn't compiled by a regular loadstring (maybe by a Java one).
definition of os.loadAPI in the bios :definition of sPath in the shell program :shell.path and shell.setPath :Shell.programs using sPath :
[I've CC 1.5]
I usually read the built in programs for some inspiration, and I found something I can hardly explain. In the shell, there are local variables like sPath or tEnv declared at the beginning which give the paths to search the programs, or the environment used at this level of shell, and everything goes well, we can access to sPath with shell.path and shell.setPath, and tEnv is well used while running programs, new shells included.
And now, in the bios, before the declaration of os.loadAPI, there is a local table declared to ensure that an API is not loaded twice. But that doesn't work at all! When I call os.loadAPI on the same API twice in the lua prompt, or even twice on a row in the same program, I do not raise the error "API "..sName.." is already being loaded". I'm very curious to know how it works. I haven't yet tried to load twice the same API in the bios, cause I didn't fell like changing it, but I think this could be very informative.
My hypothesis, though I do not convince myself, is that the bios isn't compiled by a regular loadstring (maybe by a Java one).
definition of os.loadAPI in the bios :
Spoiler
local tAPIsLoading = {}
function os.loadAPI( _sPath )
local sName = fs.getName( _sPath )
if tAPIsLoading[sName] == true then
printError( "API "..sName.." is already being loaded" )
return false
end
tAPIsLoading[sName] = true
local tEnv = {}
setmetatable( tEnv, { __index = _G } )
local fnAPI, err = loadfile( _sPath )
if fnAPI then
setfenv( fnAPI, tEnv )
fnAPI()
else
printError( err )
tAPIsLoading[sName] = nil
return false
end
local tAPI = {}
for k,v in pairs( tEnv ) do
tAPI[k] = v
end
_G[sName] = tAPI
tAPIsLoading[sName] = nil
return true
end
Spoiler
local sPath = (parentShell and parentShell.path()) or ".:/rom/programs"
Spoiler
function shell.path()
return sPath
end
function shell.setPath( _sPath )
sPath = _sPath
end
Spoiler
function shell.programs( _bIncludeHidden )
local tItems = {}
-- Add programs from the path
for sPath in string.gmatch(sPath, "[^:]+") do
sPath = shell.resolve( sPath )
if fs.isDir( sPath ) then
local tList = fs.list( sPath )
for n,sFile in pairs( tList ) do
if not fs.isDir( fs.combine( sPath, sFile ) ) and
(_bIncludeHidden or string.sub( sFile, 1, 1 ) ~= ".") then
tItems[ sFile ] = true
end
end
end
end
-- Sort and return
local tItemList = {}
for sItem, b in pairs( tItems ) do
table.insert( tItemList, sItem )
end
table.sort( tItemList )
return tItemList
end