Skip to content

Commit 24b6a43

Browse files
committed
Create POSIX safe filename function
Signed-off-by: Jono Yang <jyang@nexb.com>
1 parent d3eed9a commit 24b6a43

1 file changed

Lines changed: 34 additions & 0 deletions

File tree

src/commoncode/paths.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,40 @@ def portable_filename(filename, preserve_spaces=False):
198198

199199
return filename
200200

201+
202+
posix_legal_punctuation = r"!@#$%^&\*\(\)-_=\+\[\{\]\}\\\|;:'\",<.>\/\?`~\ "
203+
posix_legal_characters = r"A-Za-z0-9" + posix_legal_punctuation
204+
posix_illegal_characters_re = r"[^" + posix_legal_characters + r"]"
205+
replace_illegal_posix_chars = re.compile(posix_illegal_characters_re).sub
206+
207+
208+
def posix_safe_filename(filename):
209+
"""
210+
Return a new name for `filename` that is portable across POSIX systems.
211+
212+
Filenames returned by `posix_safe_filename` are not guarenteed to be valid
213+
on Windows systems as they may contain characters not allowed in Windows
214+
filenames.
215+
"""
216+
filename = toascii(filename, translit=True)
217+
218+
if not filename:
219+
return '_'
220+
221+
filename = replace_illegal_posix_chars('_', filename)
222+
223+
# no name made only of dots.
224+
if set(filename) == set(['.']):
225+
filename = 'dot' * len(filename)
226+
227+
# replaced any leading dotdot
228+
if filename != '..' and filename.startswith('..'):
229+
while filename.startswith('..'):
230+
filename = filename.replace('..', '__', 1)
231+
232+
return filename
233+
234+
201235
#
202236
# paths comparisons, common prefix and suffix extraction
203237
#

0 commit comments

Comments
 (0)