# Copyright 2026 SigmaSRC, Inc. All Rights Reserved.

"""Convert file mode to ls-style strings."""

import stat

kindmap = {
    stat.S_IFDIR: 'd',
    stat.S_IFCHR: 'c',
    stat.S_IFBLK: 'b',
    stat.S_IFREG: '-',
    stat.S_IFIFO: 'f',
    stat.S_IFLNK: 'l',
    stat.S_IFSOCK: 's',
    }

specialmap = {
    stat.S_ISUID: 's',
    stat.S_ISGID: 'g',
    stat.S_ISVTX: 't',
    }

rwxmap = {
    0o400: 'r',
    0o200: 'w',
    0o100: 'x',
    0o040: 'r',
    0o020: 'w',
    0o010: 'x',
    0o004: 'r',
    0o002: 'w',
    0o001: 'x',
    }

def mapbits(mode, shift, map):
    s = ""
    for i in (2, 1, 0):
        s += map.get(mode & (1 << (shift+i)), '-')
    return s

def modestr(mode):
    """Convert file mode to ls-style strings.

    Given a file mode (the st_mode field of an os.stat() return
    value), return a tuple of five strings:

        (kind, special, owner, group, other)

    - kind: '-' for a regular file, 'd' for a directory, etc.

    - special: three characters; the first 's' for set-uid, the second
      'g' for setgid, the third 't' for sticky; each is '-' if the
      corresponding bit is not set.

    - owner, group, other: three characters; the first 'r' for
      readable, the second 'w' for writable, the third 'x' for
      executable; each is '-' if the corresponding bit is not set.

    """
    kind = kindmap.get(stat.S_IFMT(mode), '?')
    special = mapbits(mode, 9, specialmap)
    owner =  mapbits(mode, 6, rwxmap)
    group =  mapbits(mode, 3, rwxmap)
    other =  mapbits(mode, 0, rwxmap)
    return kind, special, owner, group, other

def test():
    import os
    for name in os.listdir(os.curdir):
        st = os.stat(name)
        print(modestr(st.st_mode), name)

if __name__ == "__main__":
    test()
