Page 1 of 1

compiler does not see local function

Posted: 01 Sep 2022 20:25
by Ron Melby
simple selection code
if you have a file root, and at record selection window, you press cancel it will ask you if you want to use the file root
if you press Cancel Button on the do you want to use the file root screen, it returns cancel to the program
if you press Enter button it sets up global pointers.

both local functions are defined before line 83 inside the local function sltROOT

however, there is an error, and I do not understand why it is looking for a global function when there is a local function already defined.

debug gives:
83: attempt to call global 'choose_root' (a nil value)

Code: Select all

-- str sltROOT variables
local WS_CANCEL = false
local WS_Cancel = 'Cancel'
local WS_ENTER  = true
local WS_OK     = 'OK'
local _slt = {}
-- end sltROOT variables

-- select root
local function sltROOT()

  _slt['_root'] = {fn_key = '', _YROOT = '',  _YFATHER = '', _YMOTHER = '', _YFAM = ''}
  local _root
  local ptrFAM = fhNewItemPtr()
  local lnkFAM = fhNewItemPtr()

  local WS_RC

  -- choose root. if cancel key is pressed and there is a file root, ask to use it.
  local function mat_global_roots()

    ptrFAM = fhGetItemPtr(_YROOT, '~.FAMC')
    lnkFAM = fhGetValueAsLink(ptrFAM)

    if ptrFAM:IsNotNull() then

      local lnkHUSB = fhNewItemPtr()
      local ptrHUSB = fhNewItemPtr()
      lnkHUSB = fhGetItemPtr(lnkFAM, '~.HUSB[1]>')
      ptrHUSB = fhGetItemPtr(lnkFAM, '~.HUSB[2]>')

      local lnkWIFE = fhNewItemPtr()
      local ptrWIFE = fhNewItemPtr()
      lnkWIFE = fhGetItemPtr(lnkFAM, '~.WIFE[1]>')
      ptrWIFE = fhGetItemPtr(lnkFAM, '~.WIFE[2]>')

      -- same sex male
      if lnkHUSB:IsNotNull() and ptrHUSB:IsNotNull() then lnkWIFE = ptrHUSB end
      -- same sex female
      if lnkWIFE:IsNotNull() and ptrWIFE:IsNotNull() then lnkHUSB = lnkWIFE lnkWIFE = ptrWIFE end

      _YFATHER = lnkHUSB
      _YMOTHER = lnkWIFE
      _YFAM = lnkFAM

      _slt['_root'].fn_key = WS_ENTER
      _slt['_root']._YROOT = _YROOT
      _slt['_root']._YFATHER = lnkHUSB
      _slt['_root']._YMOTHER = lnkWIFE
      _slt['_root']._YFAM = lnkFAM
    end
  end -- fn mat_global_roots

  local function choose_root()
    local txt
    _YROOT = fhCallBuiltInFunction('FileRoot')
    if _YROOT:IsNull()then
      txt = 'File Root not set: Requires Root'
    else
      local fileroot = fhGetItemText(_YROOT, '~.NAME')
      txt = ('Use File Root: %s'):format(fileroot)
    end

    WS_RC = fhMessageBox(txt, 'MB_OKCANCEL')
    if WS_RC == WS_OK then
      if _YROOT:IsNotNull()then
        mat_global_roots()
      else
        WS_RC = sltROOT()
        if WS_RC == WS_Cancel then
          _slt['_root'].fn_key = WS_CANCEL
        end
      end
    elseif WS_RC == WS_Cancel then
      _slt['_root'].fn_key = WS_CANCEL
    end
  end
end  -- fn choose_root

-- *ENTRY()
_root = fhPromptUserForRecordSel('INDI', 1)
if #_root == 0 then
  choose_root()
  if  _slt['_root'].fn_key ~= WS_CANCEL then
    _YROOT = _root[1]
    mat_global_roots()
  end
  return _slt['_root']
end --fn sltROOT

local _root = sltROOT()
return

Re: compiler does not see local function

Posted: 01 Sep 2022 20:52
by Ron Melby
after staring at this since 5:30 this morning trying to figure it out all of a sudden I see an end out of place. thanks for looking.

Re: compiler does not see local function

Posted: 01 Sep 2022 21:05
by tatewise
You have not got your end statements correct.

As it stands, the code starting on line 81 is outside the local function sltROOT() so its local function mat_global_roots() and local function choose_root() are not in scope. i.e. That line 81 code runs as soon as you click Go without calling sltROOT() and those functions and local variables such as lnkHUSB, ptrHUSB, lnkWIFE, ptrWIFE are not listed in the variables pane.

Line 78 end should not exist and its comment -- fn choose_root belongs on line 77.

The line 89 comment --fn sltROOT should be on line 93.

Line 95 needs sltROOT() to call the function initially.

However, that only resolves the scoping issue. There still seem to be logical problems.

Re: compiler does not see local function

Posted: 01 Sep 2022 21:53
by Ron Melby
Mike, in a post not shown up yet, after staring at that piece of scrap since 5:30, this morning, it came to me just after I posted it. change after change left that end out of place.

here it is fixed up (I have simplified my '_STD_SLT':sltROT() logic written long ago, when I couldn't program any better then than now, either.

the last few posts I have out here are all towards a better, faster and easier to use order families module which is currently giving me a fit:
but I will ask the (to me0 rather complex involved question when I post that code.

in any case, here is my better faster sltROOT() which I am sure someone can find a problem with.... LOL.

Code: Select all

-- str sltROOT variables
local WS_CANCEL = false
local WS_Cancel = 'Cancel'
local WS_ENTER  = true
local WS_OK     = 'OK'
local _slt = {}
-- end sltROOT variables

-- select root
local function sltROOT()

  _slt['_root'] =
  {fn_key = '', _YROOT = '',  _YFATHER = '', _YMOTHER = '', _YFAM = '', _CROOT = '',  _CFATHER = '', _CMOTHER = '', _CFAM = ''}

  local WS_RC

  -- choose root. if cancel key is pressed and there is a file root, ask to use it.
  local function mat_spc_root()

    local ptrFAM = fhGetItemPtr(_YROOT, '~.FAMC')
    local lnkFAM = fhGetValueAsLink(ptrFAM)

    if ptrFAM:IsNotNull() then
      lnkHUSB = fhGetItemPtr(lnkFAM, '~.HUSB[1]>')
      ptrHUSB = fhGetItemPtr(lnkFAM, '~.HUSB[2]>')
      lnkWIFE = fhGetItemPtr(lnkFAM, '~.WIFE[1]>')
      ptrWIFE = fhGetItemPtr(lnkFAM, '~.WIFE[2]>')

      -- same sex male
      if lnkHUSB:IsNotNull() and ptrHUSB:IsNotNull() then lnkWIFE = ptrHUSB end
      -- same sex female
      if lnkWIFE:IsNotNull() and ptrWIFE:IsNotNull() then lnkHUSB = lnkWIFE lnkWIFE = ptrWIFE end

      _CROOT = fhGetRecordId(_YROOT)
      _YFATHER = lnkHUSB
      _CFATHER = fhGetRecordId(lnkHUSB)
      _YMOTHER = lnkWIFE
      _CMOTHER = fhGetRecordId(lnkWIFE)
      _YFAM = lnkFAM
      _CFAM = fhGetRecordId(lnkFAM)

      _slt['_root'].fn_key = WS_ENTER
      _slt['_root']._YROOT = _YROOT
      _slt['_root']._YFATHER = lnkHUSB
      _slt['_root']._YMOTHER = lnkWIFE
      _slt['_root']._YFAM = lnkFAM
      _slt['_root']._CROOT = _CROOT
      _slt['_root']._CFATHER = _CFATHER
      _slt['_root']._CMOTHER = _CMOTHER
      _slt['_root']._CFAM = _CFAM
    end
  end -- fn mat_global_roots

  local function mat_file_root()
    local txt
    _YROOT = fhCallBuiltInFunction('FileRoot')
    if _YROOT:IsNull()then
      txt = 'File Root not set: plug-in requires a Root'
    else
      local fileroot = fhGetItemText(_YROOT, '~.NAME')
      txt = ('Use File Root: %s'):format(fileroot)
    end

    WS_RC = fhMessageBox(txt, 'MB_OKCANCEL')
    if WS_RC == WS_OK then
      if _YROOT:IsNotNull()then
        mat_spc_root()
      else
        sltROOT()
      end
    elseif WS_RC == WS_Cancel then
      _slt['_root'].fn_key = WS_CANCEL
    end
  end

  -- *ENTRY()
  _ = fhPromptUserForRecordSel('INDI', 1)
  if #_ == 0 then
    mat_file_root()
  elseif #_ == 1 then
    _YROOT = _[1]
    mat_spc_root()
  end
  return _slt['_root']
end --fn sltROOT

local _root = sltROOT()
return