Mercurial > gnulib
view pygnulib/module.py @ 38940:b790ffde5faa
private import even for standard modules
author | Dmitry Selyutin <ghostmansd@gmail.com> |
---|---|
date | Sat, 09 Sep 2017 23:01:51 +0300 |
parents | 3db083b5486c |
children | b7783d4403c4 |
line wrap: on
line source
#!/usr/bin/python # encoding: UTF-8 import codecs as _codecs_ import collections as _collections_ import hashlib as _hashlib_ import os as _os_ import re as _re_ from .error import type_assert as _type_assert_ class Base: """gnulib generic module""" _TABLE_ = { "description" : (0x00, str, "Description"), "comment" : (0x01, str, "Comment"), "status" : (0x02, str, "Status"), "notice" : (0x03, str, "Notice"), "applicability" : (0x04, str, "Applicability"), "files" : (0x05, list, "Files"), "dependencies" : (0x06, list, "Depends-on"), "early_autoconf_snippet" : (0x07, str, "configure.ac-early"), "autoconf_snippet" : (0x08, str, "configure.ac"), "automake_snippet" : (0x09, str, "Makefile.am"), "include" : (0x0A, list, "Include"), "link" : (0x0B, list, "Link"), "license" : (0x0C, str, "License"), "maintainers" : (0x0D, list, "Maintainer"), } _PATTERN_DEPENDENCIES_ = _re_.compile("^(\\S+)(?:\\s+(.+))*$") _PATTERN_INCLUDE_ = _re_.compile("^[\\<\"]([A-Za-z0-9/\\-_]+\\.h)[\\>\"](?:\\s+.*^)*$") def __init__(self, name, **kwargs): _type_assert_("name", name, str) self.__name = name self.__table = {"maintainers": ["all"]} for key in Base._TABLE_: self.__table[key] = "" for key, value in kwargs.items(): self.__table[key] = value @property def name(self): """name""" return self.__name @name.setter def name(self, value): _type_assert_("name", value, str) self.__name = value @property def description(self): """description""" return self.__table["description"] @description.setter def description(self, value): _type_assert_("description", value, str) self.__table["description"] = value @property def comment(self): """comment""" return self.__table["comment"] @comment.setter def comment(self, value): _type_assert_("comment", value, str) self.__table["comment"] = value @property def status(self): """status""" return self.__table["status"] @status.setter def status(self, value): _type_assert_("status", value, str) self.__table["status"] = value @property def notice(self): """notice""" return self.__table["notice"] @notice.setter def notice(self, value): _type_assert_("notice", value, str) self.__table["notice"] = value @property def applicability(self): """applicability (usually "main" or "tests")""" default = "main" if self.name.endswith("-tests") else "tests" return self.__table.get("applicability", default) @applicability.setter def applicability(self, value): _type_assert_("applicability", value, str) self.__table["applicability"] = value @property def files(self): """file dependencies iterator (set of strings)""" for file in self.__table["files"]: yield file @files.setter def files(self, value): _type_assert_("files", value, _collections_.Iterable) result = [] for item in value: _type_assert_("file", item, str) result += [item] self.__table["files"] = set(result) @property def dependencies(self): """dependencies iterator (name, condition)""" for entry in self.__table["dependencies"]: yield Base._PATTERN_DEPENDENCIES_.findall(entry)[0] @dependencies.setter def dependencies(self, value): _type_assert_("files", value, _collections_.Iterable) result = [] for (name, condition) in value: _type_assert_("name", name, str) _type_assert_("condition", condition, str) result += [(name, condition)] self.__table["dependencies"] = set(result) @property def early_autoconf_snippet(self): """early configure.ac snippet""" return self.__table["early_autoconf_snippet"] @early_autoconf_snippet.setter def early_autoconf_snippet(self, value): _type_assert_("early_autoconf_snippet", value, str) self.__table["early_autoconf_snippet"] = value @property def autoconf_snippet(self): """configure.ac snippet""" return self.__table["autoconf_snippet"] @autoconf_snippet.setter def autoconf_snippet(self, value): _type_assert_("autoconf_snippet", value, str) self.__table["autoconf_snippet"] = value @property def automake_snippet(self): """Makefile.am snippet""" return self.__table["automake_snippet"] @automake_snippet.setter def automake_snippet(self, value): _type_assert_("automake_snippet", value, str) self.__table["automake_snippet"] = value @property def include(self): """include files iterator (header, comment)""" for entry in self.__table["include"]: match = Base._PATTERN_INCLUDE_.findall(entry) yield match[0] if match else entry @include.setter def include(self, value): _type_assert_("include", value, _collections_.Iterable) result = [] for (header, comment) in value: _type_assert_("header", header, str) _type_assert_("comment", comment, str) result += [(header, comment)] self.__table["include"] = set(result) @property def link(self): """linkage iterator (string)""" for entry in self.__table["link"]: yield entry @link.setter def link(self, value): _type_assert_("link", value, _collections_.Iterable) result = [] for item in value: _type_assert_("directive", item, str) result += [item] self.__table["link"] = set(result) @property def license(self): """license""" return self.__table["license"] @license.setter def license(self, value): _type_assert_("license", value, str) self.__table["license"] = value @property def maintainers(self): """maintainers iterator (maintainer)""" for entry in self.__table["maintainers"]: yield entry @maintainers.setter def maintainers(self, value): _type_assert_("maintainers", value, _collections_.Iterable) result = [] for item in value: _type_assert_("maintainer", item, str) result += [item] self.__table["maintainers"] = set(result) def shell_variable(self, macro_prefix="gl"): """Get the name of the shell variable set to true once m4 macros have been executed.""" module = self.name if len(module) != len(module.encode()): module = (module + "\n").encode("UTF-8") module = _hashlib_.md5(module).hexdigest() return "%s_gnulib_enabled_%s" % (macro_prefix, module) def shell_function(self, macro_prefix="gl"): """Get the name of the shell function containing the m4 macros.""" module = self.name if len(module) != len(module.encode()): module = (module + "\n").encode("UTF-8") module = _hashlib_.md5(module).hexdigest() return "func_%s_gnulib_m4code_%s" % (macro_prefix, module) def conditional_name(self, macro_prefix="gl"): """Get the automake conditional name.""" module = self.name if len(module) != len(module.encode()): module = (module + "\n").encode("UTF-8") module = _hashlib_.md5(module).hexdigest() return "%s_GNULIB_ENABLED_%s" % (macro_prefix, module) def __hash__(self): return hash(str(self)) def __repr__(self): return self.__name def __str__(self): result = "" for key, (_, typeid, field) in sorted(Base._TABLE_.items(), key=lambda k: k[1][0]): field += ":\n" if typeid is list: value = "\n".join(self.__table[key]) else: value = self.__table[key] if value: result += field result += value result += "\n\n" if value else "\n" return result.strip() + "\n" def __lt__(self, value): return self.name < value.name def __le__(self, value): return self.__lt__(value) or self.__eq__(value) def __eq__(self, value): return self.name == value.name def __ne__(self, value): return not self.__eq__(value) def __ge__(self, value): return value.__le__(self) def __gt__(self, value): return value.__lt__(self) class File(Base): """gnulib module text file""" _TABLE_ = { "Description" : (str, "description"), "Comment" : (str, "comment"), "Status" : (str, "status"), "Notice" : (str, "notice"), "Applicability" : (str, "applicability"), "Files" : (list, "files"), "Depends-on" : (list, "dependencies"), "configure.ac-early" : (str, "early_autoconf_snippet"), "configure.ac" : (str, "autoconf_snippet"), "Makefile.am" : (str, "automake_snippet"), "Include" : (list, "include"), "Link" : (list, "link"), "License" : (str, "license"), "Maintainer" : (list, "maintainers"), } _FIELDS_ = [field for (_, _, field) in Base._TABLE_.values()] _PATTERN_ = _re_.compile("(%s):" % "|".join(_FIELDS_)) def __init__(self, path, mode="r", name=None, **kwargs): if name is None: name = _os_.path.basename(path) if mode not in ("r", "w", "rw"): raise ValueError("illegal mode: %r" % mode) if mode == "r": table = {} with _codecs_.open(path, "rb", "UTF-8") as stream: data = "" for line in stream: line = line.strip("\n") if line.startswith("#") \ or (line.startswith("/*") and line.endswith("*/")): continue data += (line + "\n") match = File._PATTERN_.split(data)[1:] for (group, value) in zip(match[::2], match[1::2]): (typeid, key) = File._TABLE_[group] if typeid is list: table[key] = [_ for _ in "".join(value).split("\n") if _.strip()] else: table[key] = value.strip() self.__stream = None elif mode == "w": super().__init__(name) self.__stream = _codecs_.open(path, "w+", "UTF-8") elif mode == "rw": self.__init__(path, "r") self.__stream = _codecs_.open(path, "w+", "UTF-8") else: raise ValueError("invalid mode: %r" % mode) for (key, value) in kwargs.items(): table[key] = value super().__init__(name, **table) def close(self): """Close the underlying stream and write data into the file.""" if self.__stream: self.__stream.truncate(0) self.__stream.write(str(self)) self.__stream.close() def __enter__(self): return self def __exit__(self, exctype, excval, exctrace): self.close()