Cython has moved to github.

cython-devel

view Cython/Utils.py @ 834:4695bbb3a785

Better integer literal parsing.

Now accepts U and LL suffixes, and large integer literals are longs rather than being truncated as Python objects.
author Robert Bradshaw <robertwb@math.washington.edu>
date Thu Jul 31 00:55:14 2008 -0700 (3 years ago)
parents e0bcda32af80
children 624d0463d407
line source
1 #
2 # Cython -- Things that don't belong
3 # anywhere else in particular
4 #
6 import os, sys, re, codecs
8 def replace_suffix(path, newsuf):
9 base, _ = os.path.splitext(path)
10 return base + newsuf
12 def open_new_file(path):
13 # Open and truncate existing file to
14 # preserve metadata on the Mac.
15 return open(path, "w+")
17 def castrate_file(path, st):
18 # Remove junk contents from an output file after a
19 # failed compilation, but preserve metadata on Mac.
20 # Also sets access and modification times back to
21 # those specified by st (a stat struct).
22 try:
23 f = open(path, "r+")
24 except EnvironmentError:
25 pass
26 else:
27 f.seek(0, 0)
28 f.truncate()
29 f.write(
30 "#error Do not use this file, it is the result of a failed Cython compilation.\n")
31 f.close()
32 if st:
33 os.utime(path, (st.st_atime, st.st_mtime-1))
35 def modification_time(path):
36 st = os.stat(path)
37 return st.st_mtime
39 def file_newer_than(path, time):
40 ftime = modification_time(path)
41 return ftime > time
43 # support for source file encoding detection and unicode decoding
45 def encode_filename(filename):
46 if isinstance(filename, unicode):
47 return filename
48 try:
49 filename_encoding = sys.getfilesystemencoding()
50 if filename_encoding is None:
51 filename_encoding = sys.getdefaultencoding()
52 filename = filename.decode(filename_encoding)
53 except UnicodeDecodeError:
54 pass
55 return filename
57 _match_file_encoding = re.compile(u"coding[:=]\s*([-\w.]+)").search
59 def detect_file_encoding(source_filename):
60 # PEPs 263 and 3120
61 f = codecs.open(source_filename, "rU", encoding="UTF-8")
62 try:
63 chars = []
64 for i in range(2):
65 c = f.read(1)
66 while c and c != u'\n':
67 chars.append(c)
68 c = f.read(1)
69 encoding = _match_file_encoding(u''.join(chars))
70 if encoding:
71 return encoding.group(1)
72 finally:
73 f.close()
74 return "UTF-8"
76 def open_source_file(source_filename, mode="rU"):
77 encoding = detect_file_encoding(source_filename)
78 return codecs.open(source_filename, mode=mode, encoding=encoding)
80 class EncodedString(unicode):
81 # unicode string subclass to keep track of the original encoding.
82 # 'encoding' is None for unicode strings and the source encoding
83 # otherwise
84 encoding = None
86 def byteencode(self):
87 assert self.encoding is not None
88 return self.encode(self.encoding)
90 def utf8encode(self):
91 assert self.encoding is None
92 return self.encode("UTF-8")
94 def is_unicode(self):
95 return self.encoding is None
96 is_unicode = property(is_unicode)
98 # def __eq__(self, other):
99 # return unicode.__eq__(self, other) and \
100 # getattr(other, 'encoding', '') == self.encoding
102 def escape_byte_string(s):
103 s = s.replace('\0', r'\x00')
104 try:
105 s.decode("ASCII")
106 return s
107 except UnicodeDecodeError:
108 pass
109 l = []
110 append = l.append
111 for c in s:
112 o = ord(c)
113 if o >= 128:
114 append('\\x%X' % o)
115 else:
116 append(c)
117 return ''.join(l)
119 def long_literal(value):
120 if isinstance(value, basestring):
121 if len(value) < 2:
122 value = int(value)
123 elif value[0] == 0:
124 return int(value, 8)
125 elif value[1] in 'xX':
126 return int(value[2:], 16)
127 return not -2**31 <= value < 2**31