[pypy-commit] pypy default: rearrange and support building wide versions of some environ impls, for windows
pjenvey
noreply at buildbot.pypy.org
Sat Apr 20 00:15:47 CEST 2013
Author: Philip Jenvey <pjenvey at underboss.org>
Branch:
Changeset: r63512:b57c65395e02
Date: 2013-04-19 15:12 -0700
http://bitbucket.org/pypy/pypy/changeset/b57c65395e02/
Log: rearrange and support building wide versions of some environ impls,
for windows
diff --git a/rpython/rtyper/module/ll_os_environ.py b/rpython/rtyper/module/ll_os_environ.py
--- a/rpython/rtyper/module/ll_os_environ.py
+++ b/rpython/rtyper/module/ll_os_environ.py
@@ -4,10 +4,10 @@
from rpython.rtyper.controllerentry import Controller
from rpython.rtyper.extfunc import register_external
from rpython.rtyper.lltypesystem import rffi, lltype
-from rpython.rtyper.module import ll_os
-from rpython.rlib import rposix
+from rpython.rtyper.module.support import _WIN32, StringTraits, UnicodeTraits
+from rpython.translator.tool.cbuild import ExternalCompilationInfo
-str0 = ll_os.str0
+str0 = annmodel.s_Str0
# ____________________________________________________________
#
@@ -59,85 +59,8 @@
return r_getenv
# ____________________________________________________________
-#
-# Lower-level interface: dummy placeholders and external registations
-
-def r_getenv(name):
- just_a_placeholder # should return None if name not found
-
-os_getenv = rffi.llexternal('getenv', [rffi.CCHARP], rffi.CCHARP,
- threadsafe=False)
-
-def getenv_llimpl(name):
- with rffi.scoped_str2charp(name) as l_name:
- l_result = os_getenv(l_name)
- return rffi.charp2str(l_result) if l_result else None
-
-register_external(r_getenv, [str0],
- annmodel.SomeString(can_be_None=True, no_nul=True),
- export_name='ll_os.ll_os_getenv',
- llimpl=getenv_llimpl)
-
-# ____________________________________________________________
-
-def r_putenv(name, value):
- just_a_placeholder
-
-class EnvKeepalive:
- pass
-envkeepalive = EnvKeepalive()
-envkeepalive.byname = {}
-
-os_putenv = rffi.llexternal('putenv', [rffi.CCHARP], rffi.INT)
-
-def putenv_llimpl(name, value):
- l_string = rffi.str2charp('%s=%s' % (name, value))
- error = rffi.cast(lltype.Signed, os_putenv(l_string))
- if error:
- rffi.free_charp(l_string)
- raise OSError(rposix.get_errno(), "os_putenv failed")
- # keep 'l_string' alive - we know that the C library needs it
- # until the next call to putenv() with the same 'name'.
- l_oldstring = envkeepalive.byname.get(name, lltype.nullptr(rffi.CCHARP.TO))
- envkeepalive.byname[name] = l_string
- if l_oldstring:
- rffi.free_charp(l_oldstring)
-
-register_external(r_putenv, [str0, str0], annmodel.s_None,
- export_name='ll_os.ll_os_putenv',
- llimpl=putenv_llimpl)
-
-# ____________________________________________________________
-
-def r_unsetenv(name):
- # default implementation for platforms without a real unsetenv()
- r_putenv(name, '')
-
-if hasattr(__import__(os.name), 'unsetenv'):
- os_unsetenv = rffi.llexternal('unsetenv', [rffi.CCHARP], rffi.INT)
-
- def unsetenv_llimpl(name):
- with rffi.scoped_str2charp(name) as l_name:
- error = rffi.cast(lltype.Signed, os_unsetenv(l_name))
- if error:
- raise OSError(rposix.get_errno(), "os_unsetenv failed")
- try:
- l_oldstring = envkeepalive.byname[name]
- except KeyError:
- pass
- else:
- del envkeepalive.byname[name]
- rffi.free_charp(l_oldstring)
-
- register_external(r_unsetenv, [str0], annmodel.s_None,
- export_name='ll_os.ll_os_unsetenv',
- llimpl=unsetenv_llimpl)
-
-# ____________________________________________________________
# Access to the 'environ' external variable
-from rpython.translator.tool.cbuild import ExternalCompilationInfo
-
if sys.platform.startswith('darwin'):
CCHARPPP = rffi.CArrayPtr(rffi.CCHARPP)
_os_NSGetEnviron = rffi.llexternal(
@@ -146,16 +69,21 @@
)
def os_get_environ():
return _os_NSGetEnviron()[0]
-elif sys.platform.startswith('win'):
+elif _WIN32:
+ eci = ExternalCompilationInfo(includes=['stdlib.h'])
+ CWCHARPP = lltype.Ptr(lltype.Array(rffi.CWCHARP, hints={'nolength': True}))
+
os_get_environ, _os_set_environ = rffi.CExternVariable(
- rffi.CCHARPP,
- '_environ',
- ExternalCompilationInfo(includes=['stdlib.h']))
+ rffi.CCHARPP, '_environ', eci)
+ get__wenviron, _set__wenviron = rffi.CExternVariable(
+ CWCHARPP, '_wenviron', eci, c_type='wchar_t **')
else:
os_get_environ, _os_set_environ = rffi.CExternVariable(
rffi.CCHARPP, 'environ', ExternalCompilationInfo())
# ____________________________________________________________
+#
+# Lower-level interface: dummy placeholders and external registations
def r_envkeys():
just_a_placeholder
@@ -181,18 +109,109 @@
def r_envitems():
just_a_placeholder
-def envitems_llimpl():
- environ = os_get_environ()
- result = []
- i = 0
- while environ[i]:
- name_value = rffi.charp2str(environ[i])
- p = name_value.find('=')
- if p >= 0:
- result.append((name_value[:p], name_value[p+1:]))
- i += 1
- return result
+def r_getenv(name):
+ just_a_placeholder # should return None if name not found
+
+def r_putenv(name, value):
+ just_a_placeholder
+
+os_getenv = rffi.llexternal('getenv', [rffi.CCHARP], rffi.CCHARP,
+ threadsafe=False)
+os_putenv = rffi.llexternal('putenv', [rffi.CCHARP], rffi.INT)
+if _WIN32:
+ _wgetenv = rffi.llexternal('_wgetenv', [rffi.CWCHARP], rffi.CWCHARP,
+ compilation_info=eci, threadsafe=False)
+ _wputenv = rffi.llexternal('_wputenv', [rffi.CWCHARP], rffi.INT,
+ compilation_info=eci)
+
+class EnvKeepalive:
+ pass
+envkeepalive = EnvKeepalive()
+envkeepalive.byname = {}
+envkeepalive.bywname = {}
+
+def make_env_impls(win32=False):
+ if not win32:
+ traits = StringTraits()
+ get_environ, getenv, putenv = os_get_environ, os_getenv, os_putenv
+ byname, eq = envkeepalive.byname, '='
+ def last_error(msg):
+ from rpython.rlib import rposix
+ raise OSError(rposix.get_errno(), msg)
+ else:
+ traits = UnicodeTraits()
+ get_environ, getenv, putenv = get__wenviron, _wgetenv, _wputenv
+ byname, eq = envkeepalive.bywname, u'='
+ from rpython.rlib.rwin32 import lastWindowsError as last_error
+
+ def envitems_llimpl():
+ environ = get_environ()
+ result = []
+ i = 0
+ while environ[i]:
+ name_value = traits.charp2str(environ[i])
+ p = name_value.find(eq)
+ if p >= 0:
+ result.append((name_value[:p], name_value[p+1:]))
+ i += 1
+ return result
+
+ def getenv_llimpl(name):
+ with traits.scoped_str2charp(name) as l_name:
+ l_result = getenv(l_name)
+ return traits.charp2str(l_result) if l_result else None
+
+ def putenv_llimpl(name, value):
+ l_string = traits.str2charp(name + eq + value)
+ error = rffi.cast(lltype.Signed, putenv(l_string))
+ if error:
+ traits.free_charp(l_string)
+ last_error("putenv failed")
+ # keep 'l_string' alive - we know that the C library needs it
+ # until the next call to putenv() with the same 'name'.
+ l_oldstring = byname.get(name, lltype.nullptr(traits.CCHARP.TO))
+ byname[name] = l_string
+ if l_oldstring:
+ traits.free_charp(l_oldstring)
+
+ return envitems_llimpl, getenv_llimpl, putenv_llimpl
+
+envitems_llimpl, getenv_llimpl, putenv_llimpl = make_env_impls()
register_external(r_envitems, [], [(str0, str0)],
export_name='ll_os.ll_os_envitems',
llimpl=envitems_llimpl)
+register_external(r_getenv, [str0],
+ annmodel.SomeString(can_be_None=True, no_nul=True),
+ export_name='ll_os.ll_os_getenv',
+ llimpl=getenv_llimpl)
+register_external(r_putenv, [str0, str0], annmodel.s_None,
+ export_name='ll_os.ll_os_putenv',
+ llimpl=putenv_llimpl)
+
+# ____________________________________________________________
+
+def r_unsetenv(name):
+ # default implementation for platforms without a real unsetenv()
+ r_putenv(name, '')
+
+if hasattr(__import__(os.name), 'unsetenv'):
+ os_unsetenv = rffi.llexternal('unsetenv', [rffi.CCHARP], rffi.INT)
+
+ def unsetenv_llimpl(name):
+ with rffi.scoped_str2charp(name) as l_name:
+ error = rffi.cast(lltype.Signed, os_unsetenv(l_name))
+ if error:
+ from rpython.rlib import rposix
+ raise OSError(rposix.get_errno(), "os_unsetenv failed")
+ try:
+ l_oldstring = envkeepalive.byname[name]
+ except KeyError:
+ pass
+ else:
+ del envkeepalive.byname[name]
+ rffi.free_charp(l_oldstring)
+
+ register_external(r_unsetenv, [str0], annmodel.s_None,
+ export_name='ll_os.ll_os_unsetenv',
+ llimpl=unsetenv_llimpl)
More information about the pypy-commit
mailing list