File: bm_util.py

package info (click to toggle)
c4core 0.2.7-1
  • links: PTS
  • area: main
  • in suites: forky, sid
  • size: 5,184 kB
  • sloc: cpp: 35,521; python: 2,786; javascript: 414; makefile: 6
file content (147 lines) | stat: -rw-r--r-- 3,211 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import os
import json
import yaml
import shutil
import mmh3
import itertools
import munch
import enum


# --------------------------------------------------------

class _enum(enum.Enum):
    def __str__(self):
        return str(self.name)

    @property
    def short(self):
        return self.name

    @classmethod
    def make(cls, s):
        try:
            return cls[s]
        except:
            cls.err_unknown(s)

    @classmethod
    def err_unknown(cls, s):
        raise Exception(f"unknown {__class__.__name__}: {s}")


class FundamentalTypes(_enum):
    float = "float"
    double = "double"
    int8_t = "int8_t"
    uint8_t = "uint8_t"
    int16_t = "int16_t"
    uint16_t = "uint16_t"
    int32_t = "int32_t"
    uint32_t = "uint32_t"
    int64_t = "int64_t"
    uint64_t = "uint64_t"
    @property
    def short(self):
        return self.name.replace("uint", "u").replace("int", "i").replace("_t", "")


# --------------------------------------------------------

def log(*args, **kwargs):
    print(*args, **kwargs, flush=True)


def myhash_combine(curr, value):
    return curr ^ (value + 0x9e3779b9 + (curr << 6) + (curr >> 2))


def first(iterable):
    """Returns the first item"""
    if isinstance(iterable, list):
        return iterable[0]
    return next(iterable)


def chain(*iterables):
    for it in iterables:
        for elm in it:
            yield elm


def nth(iterable, n, default=None):
    """Returns the nth item or a default value"""
    return next(itertools.islice(iterable, n, None), default)


def optionals(obj, *attrs):
    ret = []
    for attr in attrs:
        if not hasattr(obj, attr):
            log("attr not present:", attr)
            continue
        ret.append(getattr(obj, attr))
    return ret


def myhash(*args):
    h = 137597
    for a in args:
        if isinstance(a, str):
            if a == "":
                continue
            b = bytes(a, "utf8")
        else:
            b = bytes(a)
        hb = mmh3.hash(b, signed=False)
        h = myhash_combine(h, hb)
    s = hex(h)
    return s[2:min(10, len(s))]


def copy_file_to_dir(file, dir):
    dir = os.path.abspath(dir)
    src = os.path.abspath(file)
    dst = f"{dir}/{os.path.basename(src)}"
    if not os.path.exists(dir):
        os.makedirs(dir)
    if os.path.exists(dst):
        os.remove(dst)
    log("copy:", src, "-->", dst)
    shutil.copy(src, dst)
    return dst


def chk(f):
    log("looking for file:", f)
    assert os.path.exists(f), f
    return f


def load_yml_file(filename):
    if not os.path.exists(filename):
        raise Exception(f"not found: {filename}")
    with open(filename) as f:
        return load_yml(f.read())


def dump_yml(data, filename):
    with open(filename, "w") as f:
        yaml.safe_dump(data, f)


def load_yml(yml):
    return munch.munchify(yaml.safe_load(yml))


def dump_json(data, filename):
    with open(filename, "w") as f:
        f.write(json.dumps(data, indent=2, sort_keys=True))


def load_json(filename):
    with open(filename, "r") as f:
        try:
            return munch.munchify(json.load(f))
        except Exception as exc:
            raise Exception(f"could not load file: {filename}: {exc}")