aboutsummaryrefslogtreecommitdiffstats
path: root/awlsim/library/library.py
blob: d541eae7d87c5c32061720d948114b3a47d5e027 (plain)
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
# -*- coding: utf-8 -*-
#
# AWL simulator - Library
#
# Copyright 2014-2017 Michael Buesch <m@bues.ch>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#

from __future__ import division, absolute_import, print_function, unicode_literals
#from awlsim.common.cython_support cimport * #@cy
from awlsim.common.compat import *

from awlsim.common.exceptions import *
from awlsim.common.dynamic_import import *


__all__ = [
	"AwlLib",
]


class AwlLib(object):
	"""AWL library."""

	__awlLibs = {}

	@classmethod
	def register(cls, libName, description):
		"""Register an AWL library."""

		libName = libName.lower()
		if libName in cls.__awlLibs:
			raise AwlSimError("Trying to register library '%s', "
				"but it does already exist.")
		cls.__awlLibs[libName] = cls(libName, description)

	@classmethod
	def registerEntry(cls, entryClass):
		"""Register an entry-class for an already registered library."""

		libName = entryClass.libraryName.lower()
		if libName not in cls.__awlLibs:
			raise AwlSimError("Trying to register element '%s' "
				"for unknown library '%s'." %\
				(str(entryClass), entryClass.libraryName))
		cls.__awlLibs[libName].entryClasses.add(entryClass)

	@classmethod
	def getByName(cls, libName):
		"""Get a library, by name."""

		libName = libName.lower()

		# Name sanity check
		try:
			if not libName.strip():
				raise ValueError
			for c in libName:
				if not isalnum(c) and c != "_":
					raise ValueError
		except ValueError:
			raise AwlSimError("Library name '%s' "
				"is invalid." % libName)

		# Get the module and return the class
		try:
			importModule("awlsim.library.%s" % libName)
			return cls.__awlLibs[libName]
		except (ImportError, KeyError) as e:
			raise AwlSimError("Library '%s' was not found "
				"in the standard library catalog." %\
				libName)

	@classmethod
	def getEntryBySelection(cls, selection):
		"""Get a library entry class by AwlLibEntrySelection().
		selection -> An AwlLibEntrySelection instance."""

		return cls.getByName(selection.getLibName()).getEntry(selection)

	def __init__(self, name, description):
		self.name = name
		self.description = description
		self.entryClasses = set()

	def entries(self):
		"""Returns a sorted iterator over
		all entry classes."""

		def sortKey(cls):
			return cls.staticIndex +\
			       0x10000 if cls._isFB else 0

		for cls in sorted(self.entryClasses, key=sortKey):
			yield cls

	def getEntry(self, selection):
		"""Get a library entry class by AwlLibEntrySelection().
		selection -> An AwlLibEntrySelection instance."""

		for cls in self.entryClasses:
			if selection.getEntryType() == selection.TYPE_FC:
				if not cls._isFC:
					continue
			else:
				if not cls._isFB:
					continue
			if cls.staticIndex != selection.getEntryIndex():
				continue
			return cls
		raise AwlSimError("The selected library entry '%s' was "
			"not found." % str(selection))
bues.ch cgit interface