2018-10-30 14:58:48 +00:00
|
|
|
import io, typing
|
2019-10-10 09:32:47 +00:00
|
|
|
from src import utils
|
2018-10-30 14:58:48 +00:00
|
|
|
|
|
|
|
COMMENT_TYPES = ["#", "//"]
|
2019-05-25 20:42:42 +00:00
|
|
|
def hashflags(filename: str
|
|
|
|
) -> typing.List[typing.Tuple[str, typing.Optional[str]]]:
|
|
|
|
hashflags = [] # type: typing.List[typing.Tuple[str, typing.Optional[str]]]
|
2018-10-30 14:58:48 +00:00
|
|
|
with io.open(filename, mode="r", encoding="utf8") as f:
|
|
|
|
for line in f:
|
|
|
|
line = line.strip("\n")
|
|
|
|
found = False
|
|
|
|
for comment_type in COMMENT_TYPES:
|
|
|
|
if line.startswith(comment_type):
|
|
|
|
line = line.replace(comment_type, "", 1).lstrip()
|
|
|
|
found = True
|
|
|
|
break
|
|
|
|
|
|
|
|
if not found:
|
|
|
|
break
|
|
|
|
elif line.startswith("--"):
|
|
|
|
hashflag, sep, value = line[2:].partition(" ")
|
2019-05-25 20:42:42 +00:00
|
|
|
hashflags.append((hashflag, (value if sep else None)))
|
2019-05-25 11:58:07 +00:00
|
|
|
return hashflags
|
2018-10-30 14:58:48 +00:00
|
|
|
|
|
|
|
class Docstring(object):
|
2018-11-05 11:56:52 +00:00
|
|
|
def __init__(self, description: str, items: typing.Dict[str, str],
|
|
|
|
var_items: typing.Dict[str, typing.List[str]]):
|
2018-10-30 14:58:48 +00:00
|
|
|
self.description = description
|
|
|
|
self.items = items
|
|
|
|
self.var_items = var_items
|
|
|
|
|
|
|
|
def docstring(s: str) -> Docstring:
|
|
|
|
description = ""
|
|
|
|
last_item = None
|
2019-05-18 17:34:27 +00:00
|
|
|
last_item_no_space = False
|
2018-11-05 11:56:52 +00:00
|
|
|
items = {} # type: typing.Dict[str, str]
|
|
|
|
var_items = {} # type: typing.Dict[str, typing.List[str]]
|
2018-10-30 14:58:48 +00:00
|
|
|
if s:
|
|
|
|
for line in s.split("\n"):
|
|
|
|
line = line.strip()
|
|
|
|
|
|
|
|
if line:
|
|
|
|
if line[0] == ":":
|
|
|
|
key, _, value = line[1:].partition(": ")
|
2019-05-18 17:34:27 +00:00
|
|
|
last_item = key.lstrip("-")
|
|
|
|
last_item_no_space = key.startswith("-")
|
2018-10-30 14:58:48 +00:00
|
|
|
|
|
|
|
if key in var_items:
|
2019-05-18 17:34:27 +00:00
|
|
|
var_items[last_item].append(value)
|
2018-10-30 14:58:48 +00:00
|
|
|
elif key in items:
|
2019-05-18 17:34:27 +00:00
|
|
|
var_items[last_item] = [items.pop(last_item), value]
|
2018-10-30 14:58:48 +00:00
|
|
|
else:
|
2019-05-18 17:34:27 +00:00
|
|
|
items[last_item] = value
|
2018-10-30 14:58:48 +00:00
|
|
|
else:
|
|
|
|
if last_item:
|
2019-05-18 17:34:27 +00:00
|
|
|
if last_item_no_space:
|
|
|
|
items[last_item] += line
|
|
|
|
else:
|
|
|
|
items[last_item] += " %s" % line
|
2018-10-30 14:58:48 +00:00
|
|
|
else:
|
|
|
|
if description:
|
|
|
|
description += " "
|
|
|
|
description += line
|
|
|
|
return Docstring(description, items, var_items)
|
|
|
|
|
2018-11-11 14:43:31 +00:00
|
|
|
def keyvalue(s: str, delimiter: str=" "
|
|
|
|
) -> typing.Dict[str, typing.Optional[str]]:
|
|
|
|
items = {} # type: typing.Dict[str, typing.Optional[str]]
|
2018-11-05 11:56:28 +00:00
|
|
|
pairs = s.split(delimiter)
|
2018-11-08 22:41:30 +00:00
|
|
|
for pair in filter(None, pairs):
|
2018-11-05 11:56:28 +00:00
|
|
|
key, sep, value = pair.partition("=")
|
|
|
|
if sep:
|
|
|
|
items[key] = value
|
|
|
|
else:
|
|
|
|
items[key] = None
|
|
|
|
return items
|
2019-09-26 12:44:38 +00:00
|
|
|
|
|
|
|
def try_int(s: str) -> typing.Optional[int]:
|
|
|
|
try:
|
|
|
|
return int(s)
|
|
|
|
except ValueError:
|
|
|
|
return None
|
2019-10-10 09:32:47 +00:00
|
|
|
|
|
|
|
def line_normalise(s: str) -> str:
|
|
|
|
lines = list(filter(None, [line.strip() for line in s.split("\n")]))
|
|
|
|
return " ".join(line.replace(" ", " ") for line in lines)
|