add swidth call to determine string width on terminal

on posix platforms, this is a small wrapper around wcswidth(3).
This commit is contained in:
Thomas Waldmann 2016-05-18 04:26:43 +02:00
parent 088bccc649
commit b5404209bb
6 changed files with 44 additions and 5 deletions

View file

@ -1,10 +1,10 @@
import sys
from .platform_base import acl_get, acl_set, SyncFile, sync_dir, set_flags, get_flags, API_VERSION
from .platform_base import acl_get, acl_set, SyncFile, sync_dir, set_flags, get_flags, swidth, API_VERSION
if sys.platform.startswith('linux'): # pragma: linux only
from .platform_linux import acl_get, acl_set, SyncFile, set_flags, get_flags, API_VERSION
from .platform_linux import acl_get, acl_set, SyncFile, set_flags, get_flags, swidth, API_VERSION
elif sys.platform.startswith('freebsd'): # pragma: freebsd only
from .platform_freebsd import acl_get, acl_set, API_VERSION
from .platform_freebsd import acl_get, acl_set, swidth, API_VERSION
elif sys.platform == 'darwin': # pragma: darwin only
from .platform_darwin import acl_get, acl_set, API_VERSION
from .platform_darwin import acl_get, acl_set, swidth, API_VERSION

View file

@ -90,3 +90,11 @@ class SyncFile:
self.sync()
self.fd.close()
sync_dir(os.path.dirname(self.fd.name))
def swidth(s):
"""terminal output width of string <s>
For western scripts, this is just len(s), but for cjk glyphs, 2 cells are used.
"""
return len(s)

View file

@ -3,6 +3,12 @@ from .helpers import user2uid, group2gid, safe_decode, safe_encode
API_VERSION = 3
cdef extern from "wchar.h":
cdef int wcswidth(const Py_UNICODE *str, size_t n)
def swidth(s):
return wcswidth(s, len(s))
cdef extern from "sys/acl.h":
ctypedef struct _acl_t:
pass

View file

@ -7,6 +7,12 @@ cdef extern from "errno.h":
int errno
int EINVAL
cdef extern from "wchar.h":
cdef int wcswidth(const Py_UNICODE *str, size_t n)
def swidth(s):
return wcswidth(s, len(s))
cdef extern from "sys/types.h":
int ACL_TYPE_ACCESS
int ACL_TYPE_DEFAULT

View file

@ -9,6 +9,12 @@ from libc cimport errno
API_VERSION = 3
cdef extern from "wchar.h":
cdef int wcswidth(const Py_UNICODE *str, size_t n)
def swidth(s):
return wcswidth(s, len(s))
cdef extern from "sys/types.h":
int ACL_TYPE_ACCESS
int ACL_TYPE_DEFAULT

View file

@ -4,7 +4,7 @@ import sys
import tempfile
import unittest
from ..platform import acl_get, acl_set
from ..platform import acl_get, acl_set, swidth
from . import BaseTestCase
@ -138,3 +138,16 @@ class PlatformDarwinTestCase(BaseTestCase):
self.set_acl(file2.name, b'!#acl 1\ngroup:ABCDEFAB-CDEF-ABCD-EFAB-CDEF00000000:staff:0:allow:read\nuser:FFFFEEEE-DDDD-CCCC-BBBB-AAAA00000000:root:0:allow:read\n', numeric_owner=True)
self.assert_in(b'group:ABCDEFAB-CDEF-ABCD-EFAB-CDEF00000000:wheel:0:allow:read', self.get_acl(file2.name)[b'acl_extended'])
self.assert_in(b'group:ABCDEFAB-CDEF-ABCD-EFAB-CDEF00000000::0:allow:read', self.get_acl(file2.name, numeric_owner=True)[b'acl_extended'])
@unittest.skipUnless(sys.platform.startswith(('linux', 'freebsd', 'darwin')), 'POSIX only tests')
class PlatformPosixTestCase(BaseTestCase):
def test_swidth_ascii(self):
self.assert_equal(swidth("borg"), 4)
def test_swidth_cjk(self):
self.assert_equal(swidth("バックアップ"), 6 * 2)
def test_swidth_mixed(self):
self.assert_equal(swidth("borgバックアップ"), 4 + 6 * 2)