Patch title: Release 87 bulk changes
Abstract:
File: /pliant/language/basic/plugin.pli
Key:
    Removed line
    Added line
# Copyright  Hubert Tonneau  hubert.tonneau@pliant.cx
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 2
# as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# version 2 along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

module "/pliant/language/debug/compile_log.pli"
module "/pliant/install/ring2.pli"

constant advanced true
constant trace true


function file_database_pick filename path -> value
  arg Str filename path value
  value := ""
  var Int h := file_open pliant_root_path+".."+filename 1
  if h=(-1)
    return
  var Str char := " "
  var Str line := ""
  while (file_read h char:characters 1)=1
    if char="[lf]"
      var Int i := line search "path=[dq]" -1
      if i<>(-1)
        i := i+6
        var Int j := i+((line i line:len) search "[dq]" -1)
        if j>=i and (line i j-i)=path
          var Int k := line search ">" -1
          if k<>(-1)
            k := k+1
            var Int l := k+((line k line:len) search "<" -1)
            if l>=k
              file_close h
              value := line k l-k
      line := ""
    else
      line := line+char
  file_close h

gvar Dictionary modules
gvar Str computer_name
gvar Str computer_domain
gvar Str computer_fullname

computer_name := file_database_pick "/pliant_security/this_computer.pdb" "/env/pliant/identity/name"
computer_domain := file_database_pick "/pliant_security/this_computer.pdb" "/env/pliant/identity/domain"
if computer_domain<>""
  computer_fullname := computer_name+"."+computer_domain
else
  computer_fullname := computer_name
  
if computer_name=""
  console "Your computer name has not been found in the Pliant configuration database.[lf]"
  console "If you want you can configure it through the HTTP server,[lf]"
  console "then reexecute the Pliant installation script.[lf]"
eif false
  console "  applying plugins for "+computer_fullname+"[lf]"


meta custom e
  if e:size<>2 or not e:0:is_pure_ident
    return
  var Str name := e:module:name
  if (name 0 8)<>"/custom/"
    return
  name := name 8 name:len
  var Int i := name search "/" -1
  if i=(-1)
    return
  name := name i name:len
  name := name 0 (name search " (" name:len)
  var Pointer:Arrow c :> modules first name
  if c=null
    return
  var Pointer:Dictionary d :> c map Dictionary
  if advanced
    var Link:PackedExpression p :> e 1
    d insert e:0:ident true addressof:p
  else
    d insert e:0:ident true (addressof e:1)
  e set_void_result


function the_plugin name id -> e
  arg Str name id ; arg Link:Expression e
  var Pointer:Arrow c :> modules first name
  if c=null
    modules insert name true (addressof new:Dictionary)
    c :> modules first name
    pliant_load_module "/custom/universal"+name the_module:"/pliant/language/basic/safe.pli" 0 (null map Module)
    if computer_domain<>""
      pliant_load_module "/custom/"+computer_domain+name the_module:"/pliant/language/basic/safe.pli" 0 (null map Module)
    if computer_fullname<>""
      pliant_load_module "/custom/"+computer_fullname+name the_module:"/pliant/language/basic/safe.pli" 0 (null map Module)
  var Pointer:Dictionary d :> c map Dictionary
  c :> d first id
  if c<>null
    if advanced
      e :> c map PackedExpression
    else
      e :> c map Expression
  else
    e :> null map Expression

method e switch_module m
  arg_rw Expression e ; arg Module m
  e module :> m
  for (var Int i) 0 e:size-1
    e:i switch_module m

meta plugin e
  if e:size<1 or e:size>2 or not e:0:is_pure_ident
    return
  var Str name := e:module:name
  name := name 0 (name search " (" name:len)
  var Link:Expression p :> the_plugin name e:0:ident
  if addressof:p<>null
    if trace
      console "  applying plugin "+name+" "+e:0:ident+"[lf]"
      compile_log "applying plugin "+name+" "+e:0:ident
    p switch_module e:module
    p compile
    if p:is_compiled
      e suckup p
      e set_result p:result p:access
  eif e:size=1
    e set_void_result
  else
    e:1:compile
    if e:1:is_compiled
      e suckup e:1
      e set_result e:1:result e:1:access
    

export custom plugin