Tidy PLCopen definitions
authorEdouard Tisserant
Tue, 28 Jan 2014 16:24:40 +0100
changeset 1390 0f4d32a033e0
parent 1389 fb19c6226ff5
child 1391 f6818bb5e292
Tidy PLCopen definitions
PLCControler.py
plcopen/__init__.py
plcopen/definitions.py
plcopen/iec_std.csv
plcopen/structures.py
--- a/PLCControler.py	Mon Jan 27 14:45:12 2014 +0100
+++ b/PLCControler.py	Tue Jan 28 16:24:40 2014 +0100
@@ -117,7 +117,7 @@
             if lib_name == "project":
                 lib_el.append(deepcopy(self.Controller.GetProject(self.Debug)))
             elif lib_name == "stdlib":
-                for lib in [StdBlockLibrary, AddnlBlockLibrary]:
+                for lib in StdBlckLibs.values():
                     lib_el.append(deepcopy(lib))
             else:
                 for ctn in self.Controller.ConfNodeTypes:
@@ -1689,7 +1689,7 @@
             result = project.getpou(typename)
             if result is not None:
                 return result
-        for standardlibrary in [StdBlockLibrary, AddnlBlockLibrary]:
+        for standardlibrary in StdBlckLibs.values():
             result = standardlibrary.getpou(typename)
             if result is not None:
                 return result
--- a/plcopen/__init__.py	Mon Jan 27 14:45:12 2014 +0100
+++ b/plcopen/__init__.py	Tue Jan 28 16:24:40 2014 +0100
@@ -25,7 +25,8 @@
 # Package initialisation
 
 # plcopen module dynamically creates its classes
+
 from plcopen import PLCOpenParser, LoadProject, SaveProject, LoadPou, \
     LoadPouInstances, VarOrder, QualifierList, rect
 
-from structures import *
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plcopen/definitions.py	Tue Jan 28 16:24:40 2014 +0100
@@ -0,0 +1,164 @@
+from os.path import join, split, realpath
+sd = split(realpath(__file__))[0]
+
+# Override gettext _ in this module
+# since we just want string to be added to dictionnary
+# but translation should happen here
+_ = lambda x:x
+
+LANGUAGES = ["IL","ST","FBD","LD","SFC"]
+
+LOCATIONDATATYPES = {"X" : ["BOOL"],
+                     "B" : ["SINT", "USINT", "BYTE", "STRING"],
+                     "W" : ["INT", "UINT", "WORD", "WSTRING"],
+                     "D" : ["DINT", "UDINT", "REAL", "DWORD"],
+                     "L" : ["LINT", "ULINT", "LREAL", "LWORD"]} 
+
+#-------------------------------------------------------------------------------
+#                        Function Block Types definitions
+#-------------------------------------------------------------------------------
+
+StdTC6Libs = [(_("Standard function blocks"),  join(sd, "Standard_Function_Blocks.xml")),
+              (_("Additional function blocks"),join(sd, "Additional_Function_Blocks.xml"))]
+
+StdFuncsCSV = join(sd,"iec_std.csv")
+
+# FIXME : since std fb now loaded from TC6 file, is that still necessary ?
+StdBlockComments = {
+    "SR": _("SR bistable\nThe SR bistable is a latch where the Set dominates."),
+    "RS": _("RS bistable\nThe RS bistable is a latch where the Reset dominates."),
+    "SEMA": _("Semaphore\nThe semaphore provides a mechanism to allow software elements mutually exclusive access to certain ressources."),
+    "R_TRIG": _("Rising edge detector\nThe output produces a single pulse when a rising edge is detected."),
+    "F_TRIG": _("Falling edge detector\nThe output produces a single pulse when a falling edge is detected."),
+    "CTU": _("Up-counter\nThe up-counter can be used to signal when a count has reached a maximum value."),
+    "CTD": _("Down-counter\nThe down-counter can be used to signal when a count has reached zero, on counting down from a preset value."),
+    "CTUD": _("Up-down counter\nThe up-down counter has two inputs CU and CD. It can be used to both count up on one input and down on the other."),
+    "TP": _("Pulse timer\nThe pulse timer can be used to generate output pulses of a given time duration."),
+    "TON": _("On-delay timer\nThe on-delay timer can be used to delay setting an output true, for fixed period after an input becomes true."),
+    "TOF": _("Off-delay timer\nThe off-delay timer can be used to delay setting an output false, for fixed period after input goes false."),
+    "RTC": _("Real time clock\nThe real time clock has many uses including time stamping, setting dates and times of day in batch reports, in alarm messages and so on."),
+    "INTEGRAL": _("Integral\nThe integral function block integrates the value of input XIN over time."),
+    "DERIVATIVE": _("Derivative\nThe derivative function block produces an output XOUT proportional to the rate of change of the input XIN."),
+    "PID": _("PID\nThe PID (proportional, Integral, Derivative) function block provides the classical three term controller for closed loop control."),
+    "RAMP": _("Ramp\nThe RAMP function block is modelled on example given in the standard."),
+    "HYSTERESIS": _("Hysteresis\nThe hysteresis function block provides a hysteresis boolean output driven by the difference of two floating point (REAL) inputs XIN1 and XIN2."),
+}
+
+for block_type in ["CTU", "CTD", "CTUD"]:
+    for return_type in ["DINT", "LINT", "UDINT", "ULINT"]:
+        StdBlockComments["%s_%s" % (block_type, return_type)] = StdBlockComments[block_type]
+
+def GetBlockInfos(pou):
+    infos = pou.getblockInfos()
+    # FIXME : as well
+    infos["comment"] = StdBlockComments[infos["name"]]
+    infos["inputs"] = [
+        (var_name, var_type, "rising")
+        if var_name in ["CU", "CD"]
+        else (var_name, var_type, var_modifier)
+        for var_name, var_type, var_modifier in infos["inputs"]]
+    return infos
+
+#-------------------------------------------------------------------------------
+#                           Data Types definitions
+#-------------------------------------------------------------------------------
+
+"""
+Ordored list of common data types defined in the IEC 61131-3
+Each type is associated to his direct parent type. It defines then a hierarchy
+between type that permits to make a comparison of two types
+"""
+TypeHierarchy_list = [
+    ("ANY", None),
+    ("ANY_DERIVED", "ANY"),
+    ("ANY_ELEMENTARY", "ANY"),
+    ("ANY_MAGNITUDE", "ANY_ELEMENTARY"),
+    ("ANY_BIT", "ANY_ELEMENTARY"),
+    ("ANY_NBIT", "ANY_BIT"),
+    ("ANY_STRING", "ANY_ELEMENTARY"),
+    ("ANY_DATE", "ANY_ELEMENTARY"),
+    ("ANY_NUM", "ANY_MAGNITUDE"),
+    ("ANY_REAL", "ANY_NUM"),
+    ("ANY_INT", "ANY_NUM"),
+    ("ANY_SINT", "ANY_INT"),
+    ("ANY_UINT", "ANY_INT"),
+    ("BOOL", "ANY_BIT"),
+    ("SINT", "ANY_SINT"),
+    ("INT", "ANY_SINT"),
+    ("DINT", "ANY_SINT"),
+    ("LINT", "ANY_SINT"),
+    ("USINT", "ANY_UINT"),
+    ("UINT", "ANY_UINT"),
+    ("UDINT", "ANY_UINT"),
+    ("ULINT", "ANY_UINT"),
+    ("REAL", "ANY_REAL"),
+    ("LREAL", "ANY_REAL"),
+    ("TIME", "ANY_MAGNITUDE"),
+    ("DATE", "ANY_DATE"),
+    ("TOD", "ANY_DATE"),
+    ("DT", "ANY_DATE"),
+    ("STRING", "ANY_STRING"),
+    ("BYTE", "ANY_NBIT"),
+    ("WORD", "ANY_NBIT"),
+    ("DWORD", "ANY_NBIT"),
+    ("LWORD", "ANY_NBIT")
+    #("WSTRING", "ANY_STRING") # TODO
+]
+
+DataTypeRange_list = [
+    ("SINT", (-2**7, 2**7 - 1)),
+    ("INT", (-2**15, 2**15 - 1)),
+    ("DINT", (-2**31, 2**31 - 1)),
+    ("LINT", (-2**31, 2**31 - 1)),
+    ("USINT", (0, 2**8 - 1)),
+    ("UINT", (0, 2**16 - 1)),
+    ("UDINT", (0, 2**31 - 1)),
+    ("ULINT", (0, 2**31 - 1))
+]
+
+ANY_TO_ANY_FILTERS = {
+    "ANY_TO_ANY":[
+        # simple type conv are let as C cast
+        (("ANY_INT","ANY_BIT"),("ANY_NUM","ANY_BIT")),
+        (("ANY_REAL",),("ANY_REAL",)),
+        # REAL_TO_INT
+        (("ANY_REAL",),("ANY_SINT",)),
+        (("ANY_REAL",),("ANY_UINT",)),
+        (("ANY_REAL",),("ANY_BIT",)),
+        # TO_TIME
+        (("ANY_INT","ANY_BIT"),("ANY_DATE","TIME")),
+        (("ANY_REAL",),("ANY_DATE","TIME")),
+        (("ANY_STRING",), ("ANY_DATE","TIME")),
+        # FROM_TIME
+        (("ANY_DATE","TIME"), ("ANY_REAL",)),
+        (("ANY_DATE","TIME"), ("ANY_INT","ANY_NBIT")),
+        (("TIME",), ("ANY_STRING",)),
+        (("DATE",), ("ANY_STRING",)),
+        (("TOD",), ("ANY_STRING",)),
+        (("DT",), ("ANY_STRING",)),
+        # TO_STRING
+        (("BOOL",), ("ANY_STRING",)),
+        (("ANY_BIT",), ("ANY_STRING",)),
+        (("ANY_REAL",), ("ANY_STRING",)),
+        (("ANY_SINT",), ("ANY_STRING",)),
+        (("ANY_UINT",), ("ANY_STRING",)),
+        # FROM_STRING
+        (("ANY_STRING",), ("BOOL",)),
+        (("ANY_STRING",), ("ANY_BIT",)),
+        (("ANY_STRING",), ("ANY_SINT",)),
+        (("ANY_STRING",), ("ANY_UINT",)),
+        (("ANY_STRING",), ("ANY_REAL",))],
+    "BCD_TO_ANY":[
+        (("BYTE",),("USINT",)),
+        (("WORD",),("UINT",)),
+        (("DWORD",),("UDINT",)),
+        (("LWORD",),("ULINT",))],
+    "ANY_TO_BCD":[
+        (("USINT",),("BYTE",)),
+        (("UINT",),("WORD",)),
+        (("UDINT",),("DWORD",)),
+        (("ULINT",),("LWORD",))]
+}
+
+# remove gettext override
+del _
--- a/plcopen/iec_std.csv	Mon Jan 27 14:45:12 2014 +0100
+++ b/plcopen/iec_std.csv	Tue Jan 28 16:24:40 2014 +0100
@@ -1,90 +1,90 @@
-Standard_functions_variables_types;name;type;comment;;;;;
-;N;ANY_INT;Number of bits to be shifted;;;;;
-;L;ANY_INT;Left position within character string;;;;;
-;P;ANY_INT;Position within character string;;;;;
-;G;BOOL;Selection out of 2 inputs (gate);;;;;
-;K;ANY_INT;Selection out of n inputs;;;;;
-;MN;ANY;Minimum value for limitation;;;;;
-;MX;ANY;Maximum value for limitation;;;;;
-;;;;;;;;
-;;;;;;;;
-;;;;;;;;
-;;;;;;;;
-;;;;;;;;
-;;;;;;;;
-Standard_functions_type;name;baseinputnumber;inputs;outputs;comment;extensible;python_eval_c_code_format;return_type_rule
-_("Type conversion");*_TO_**;1;(ANY);ANY;_("Data type conversion");no;ANY_TO_ANY_FORMAT_GEN(ANY_TO_ANY_LIST,fdecl);defined
-;TRUNC;1;(ANY_REAL);ANY_INT;_("Rounding up/down");no;("int", "__move_", None);&search_constant_type_c::integer
-;BCD_TO_**;1;(ANY_BIT);ANY_INT;_("Conversion from BCD");no;ANY_TO_ANY_FORMAT_GEN(BCD_TO_ANY_LIST,fdecl);defined
-;*_TO_BCD;1;(ANY_INT);ANY_BIT;_("Conversion to BCD");no;ANY_TO_ANY_FORMAT_GEN(ANY_TO_BCD_LIST,fdecl);&search_constant_type_c::integer
-;DATE_AND_TIME_TO_TIME_OF_DAY;1;(DT);TOD;_("Conversion to time-of-day");no;(None, "__date_and_time_to_time_of_day", None);defined
-;DATE_AND_TIME_TO_DATE;1;(DT);DATE;_("Conversion to date");no;(None, "__date_and_time_to_date", None);defined
-_("Numerical");ABS;1;(ANY_NUM);ANY_NUM;_("Absolute number");no;(None, "__abs_", "IN_type");IN_type_symbol
-;SQRT;1;(ANY_REAL);ANY_REAL;_("Square root (base 2)");no;(None, "__sqrt_", "IN_type");IN_type_symbol
-;LN;1;(ANY_REAL);ANY_REAL;_("Natural logarithm");no;(None, "__ln_", "IN_type");IN_type_symbol
-;LOG;1;(ANY_REAL);ANY_REAL;_("Logarithm to base 10");no;(None, "__log_", "IN_type");IN_type_symbol
-;EXP;1;(ANY_REAL);ANY_REAL;_("Exponentiation");no;(None, "__exp_", "IN_type");IN_type_symbol
-;SIN;1;(ANY_REAL);ANY_REAL;_("Sine");no;(None, "__sin_", "IN_type");IN_type_symbol
-;COS;1;(ANY_REAL);ANY_REAL;_("Cosine");no;(None, "__cos_", "IN_type");IN_type_symbol
-;TAN;1;(ANY_REAL);ANY_REAL;_("Tangent");no;(None, "__tan_", "IN_type");IN_type_symbol
-;ASIN;1;(ANY_REAL);ANY_REAL;_("Arc sine");no;(None, "__asin_", "IN_type");IN_type_symbol
-;ACOS;1;(ANY_REAL);ANY_REAL;_("Arc cosine");no;(None, "__acos_", "IN_type");IN_type_symbol
-;ATAN;1;(ANY_REAL);ANY_REAL;_("Arc tangent");no;(None, "__atan_", "IN_type");IN_type_symbol
-_("Arithmetic");ADD;1;(ANY_NUM, ANY_NUM);ANY_NUM;_("Addition");yes;(None, "__add_", "return_type");copy_input
-;MUL;1;(ANY_NUM, ANY_NUM);ANY_NUM;_("Multiplication");yes;(None, "__mul_", "return_type");copy_input
-;SUB;1;(ANY_NUM, ANY_NUM);ANY_NUM;_("Subtraction");no;(None, "__sub_", "return_type");copy_input
-;DIV;1;(ANY_NUM, ANY_NUM);ANY_NUM;_("Division");no;(None, "__div_", "return_type");copy_input
-;MOD;1;(ANY_INT, ANY_INT);ANY_INT;_("Remainder (modulo)");no;(None, "__mod_", "return_type");copy_input
-;EXPT;1;(ANY_REAL, ANY_NUM);ANY_REAL;_("Exponent");no;(None, "__expt_", "IN1_type");IN1_type_symbol
-;MOVE;1;(ANY);ANY;_("Assignment");no;(None, "__move_", "return_type");copy_input
-_("Time");ADD;1;(TIME, TIME);TIME;_("Time addition");no;(None, "__time_add", None);defined
-;ADD_TIME;1;(TIME, TIME);TIME;_("Time addition");no;(None, "__time_add", None);defined
-;ADD;1;(TOD, TIME);TOD;_("Time-of-day addition")+" "+_("DEPRECATED");no;(None, "__time_add", None);defined
-;ADD_TOD_TIME;1;(TOD, TIME);TOD;_("Time-of-day addition");no;(None, "__time_add", None);defined
-;ADD;1;(DT, TIME);DT;_("Date addition")+" "+_("DEPRECATED");no;(None, "__time_add", None);defined
-;ADD_DT_TIME;1;(DT, TIME);DT;_("Date addition");no;(None, "__time_add", None);defined
-;MUL;1;(TIME, ANY_NUM);TIME;_("Time multiplication")+" "+_("DEPRECATED");no;(None, "__time_mul", None);defined
-;MULTIME;1;(TIME, ANY_NUM);TIME;_("Time multiplication");no;(None, "__time_mul", None);defined
-;SUB_TIME;1;(TIME, TIME);TIME;_("Time subtraction");no;(None, "__time_sub", None);defined
-;SUB;1;(TIME, TIME);TIME;_("Time subtraction");no;(None, "__time_sub", None);defined
-;SUB;1;(DATE, DATE);TIME;_("Date subtraction")+" "+_("DEPRECATED");no;(None, "__time_sub", None);defined
-;SUB_DATE_DATE;1;(DATE, DATE);TIME;_("Date subtraction");no;(None, "__time_sub", None);defined
-;SUB;1;(TOD, TIME);TOD;_("Time-of-day subtraction")+" "+_("DEPRECATED");no;(None, "__time_sub", None);defined
-;SUB_TOD_TIME;1;(TOD, TIME);TOD;_("Time-of-day subtraction");no;(None, "__time_sub", None);defined
-;SUB;1;(TOD, TOD);TIME;_("Time-of-day subtraction")+" "+_("DEPRECATED");no;(None, "__time_sub", None);defined
-;SUB_TOD_TOD;1;(TOD, TOD);TIME;_("Time-of-day subtraction");no;(None, "__time_sub", None);defined
-;SUB;1;(DT, TIME);DT;_("Date and time subtraction")+" "+_("DEPRECATED");no;(None, "__time_sub", None);defined
-;SUB_DT_TIME;1;(DT, TIME);DT;_("Date and time subtraction");no;(None, "__time_sub", None);defined
-;SUB;1;(DT, DT);TIME;_("Date and time subtraction")+" "+_("DEPRECATED");no;(None, "__time_sub", None);defined
-;SUB_DT_TIME;1;(DT, DT);TIME;_("Date and time subtraction");no;(None, "__time_sub", None);defined
-;DIV;1;(TIME, ANY_NUM);TIME;_("Time division")+" "+_("DEPRECATED");no;(None, "__time_div", None);defined
-;DIVTIME;1;(TIME, ANY_NUM);TIME;_("Time division");no;(None, "__time_div", None);defined
-_("Bit-shift");SHL;1;(ANY_BIT, N);ANY_BIT;_("Shift left");no;(None, "__shl_", "IN_type");IN_type_symbol
-;SHR;1;(ANY_BIT, N);ANY_BIT;_("Shift right");no;(None, "__shr_", "IN_type");IN_type_symbol
-;ROR;1;(ANY_NBIT, N);ANY_NBIT;_("Rotate right");no;(None, "__ror_", "IN_type");IN_type_symbol
-;ROL;1;(ANY_NBIT, N);ANY_NBIT;_("Rotate left");no;(None, "__rol_", "IN_type");IN_type_symbol
-_("Bitwise");AND;1;(ANY_BIT, ANY_BIT);ANY_BIT;_("Bitwise AND");yes;(None, "__and_", "return_type");copy_input
-;OR;1;(ANY_BIT, ANY_BIT);ANY_BIT;_("Bitwise OR");yes;(None, "__or_", "return_type");copy_input
-;XOR;1;(ANY_BIT, ANY_BIT);ANY_BIT;_("Bitwise XOR");yes;(None, "__xor_", "return_type");copy_input
-;NOT;1;(ANY_BIT);ANY_BIT;_("Bitwise inverting");no;(None, "__not_", "return_type");IN_type_symbol
-_("Selection");SEL;0;(G, ANY, ANY);ANY;_("Binary selection (1 of 2)");no;(None, "__sel_", "IN0_type");copy_input
-;MAX;1;(ANY, ANY);ANY;_("Maximum");yes;(None, "__max_", "return_type");copy_input
-;MIN;1;(ANY, ANY);ANY;_("Minimum");yes;(None, "__min_", "return_type");copy_input
-;LIMIT;1;(MN, ANY, MX);ANY;_("Limitation");no;(None, "__limit_", "IN_type");IN_type_symbol
-;MUX;0;(K, ANY, ANY);ANY;_("Multiplexer (select 1 of N)");yes;(None, "__mux_", "return_type");copy_input
-_("Comparison");GT;1;(ANY, ANY);BOOL;_("Greater than");yes;(None, "__gt_", "common_type");defined
-;GE;1;(ANY, ANY);BOOL;_("Greater than or equal to");yes;(None, "__ge_", "common_type");defined
-;EQ;1;(ANY, ANY);BOOL;_("Equal to");yes;(None, "__eq_", "common_type");defined
-;LT;1;(ANY, ANY);BOOL;_("Less than");yes;(None, "__lt_", "common_type");defined
-;LE;1;(ANY, ANY);BOOL;_("Less than or equal to");yes;(None, "__le_", "common_type");defined
-;NE;1;(ANY, ANY);BOOL;_("Not equal to");no;(None, "__ne_", "common_type");defined
-_("Character string");LEN;1;(STRING);INT;_("Length of string");no;(None, "__len", None);defined
-;LEFT;1;(STRING, L);STRING;_("string left of");no;(None, "__left", None);defined
-;RIGHT;1;(STRING, L);STRING;_("string right of");no;(None, "__right", None);defined
-;MID;1;(STRING, L, P);STRING;_("string from the middle");no;(None, "__mid", None);defined
-;CONCAT;1;(STRING, STRING);STRING;_("Concatenation");yes;(None, "__concat", None);defined
-;CONCAT_DAT_TOD;1;(DATE, TOD);DT;_("Time concatenation");no;(None, "__time_add", None);defined
-;INSERT;1;(STRING, STRING, P);STRING;_("Insertion (into)");no;(None, "__insert", None);defined
-;DELETE;1;(STRING, L, P);STRING;_("Deletion (within)");no;(None, "__delete", None);defined
-;REPLACE;1;(STRING, STRING, L, P);STRING;_("Replacement (within)");no;(None, "__replace", None);defined
-;FIND;1;(STRING, STRING);INT;_("Find position");no;(None, "__find", None);defined
+Standard_functions_variables_types;name;type;comment;;;;
+;N;ANY_INT;Number of bits to be shifted;;;;
+;L;ANY_INT;Left position within character string;;;;
+;P;ANY_INT;Position within character string;;;;
+;G;BOOL;Selection out of 2 inputs (gate);;;;
+;K;ANY_INT;Selection out of n inputs;;;;
+;MN;ANY;Minimum value for limitation;;;;
+;MX;ANY;Maximum value for limitation;;;;
+;;;;;;;
+;;;;;;;
+;;;;;;;
+;;;;;;;
+;;;;;;;
+;;;;;;;
+Standard_functions_type;name;baseinputnumber;inputs;outputs;comment;extensible;filter
+_("Type conversion");*_TO_**;1;(ANY);ANY;_("Data type conversion");no;ANY_TO_ANY
+;TRUNC;1;(ANY_REAL);ANY_INT;_("Rounding up/down");no;
+;BCD_TO_**;1;(ANY_BIT);ANY_INT;_("Conversion from BCD");no;BCD_TO_ANY
+;*_TO_BCD;1;(ANY_INT);ANY_BIT;_("Conversion to BCD");no;ANY_TO_BCD
+;DATE_AND_TIME_TO_TIME_OF_DAY;1;(DT);TOD;_("Conversion to time-of-day");no;
+;DATE_AND_TIME_TO_DATE;1;(DT);DATE;_("Conversion to date");no;
+_("Numerical");ABS;1;(ANY_NUM);ANY_NUM;_("Absolute number");no;
+;SQRT;1;(ANY_REAL);ANY_REAL;_("Square root (base 2)");no;
+;LN;1;(ANY_REAL);ANY_REAL;_("Natural logarithm");no;
+;LOG;1;(ANY_REAL);ANY_REAL;_("Logarithm to base 10");no;
+;EXP;1;(ANY_REAL);ANY_REAL;_("Exponentiation");no;
+;SIN;1;(ANY_REAL);ANY_REAL;_("Sine");no;
+;COS;1;(ANY_REAL);ANY_REAL;_("Cosine");no;
+;TAN;1;(ANY_REAL);ANY_REAL;_("Tangent");no;
+;ASIN;1;(ANY_REAL);ANY_REAL;_("Arc sine");no;
+;ACOS;1;(ANY_REAL);ANY_REAL;_("Arc cosine");no;
+;ATAN;1;(ANY_REAL);ANY_REAL;_("Arc tangent");no;
+_("Arithmetic");ADD;1;(ANY_NUM, ANY_NUM);ANY_NUM;_("Addition");yes;
+;MUL;1;(ANY_NUM, ANY_NUM);ANY_NUM;_("Multiplication");yes;
+;SUB;1;(ANY_NUM, ANY_NUM);ANY_NUM;_("Subtraction");no;
+;DIV;1;(ANY_NUM, ANY_NUM);ANY_NUM;_("Division");no;
+;MOD;1;(ANY_INT, ANY_INT);ANY_INT;_("Remainder (modulo)");no;
+;EXPT;1;(ANY_REAL, ANY_NUM);ANY_REAL;_("Exponent");no;
+;MOVE;1;(ANY);ANY;_("Assignment");no;
+_("Time");ADD;1;(TIME, TIME);TIME;_("Time addition");no;
+;ADD_TIME;1;(TIME, TIME);TIME;_("Time addition");no;
+;ADD;1;(TOD, TIME);TOD;_("Time-of-day addition")+" "+_("DEPRECATED");no;
+;ADD_TOD_TIME;1;(TOD, TIME);TOD;_("Time-of-day addition");no;
+;ADD;1;(DT, TIME);DT;_("Date addition")+" "+_("DEPRECATED");no;
+;ADD_DT_TIME;1;(DT, TIME);DT;_("Date addition");no;
+;MUL;1;(TIME, ANY_NUM);TIME;_("Time multiplication")+" "+_("DEPRECATED");no;
+;MULTIME;1;(TIME, ANY_NUM);TIME;_("Time multiplication");no;
+;SUB_TIME;1;(TIME, TIME);TIME;_("Time subtraction");no;
+;SUB;1;(TIME, TIME);TIME;_("Time subtraction");no;
+;SUB;1;(DATE, DATE);TIME;_("Date subtraction")+" "+_("DEPRECATED");no;
+;SUB_DATE_DATE;1;(DATE, DATE);TIME;_("Date subtraction");no;
+;SUB;1;(TOD, TIME);TOD;_("Time-of-day subtraction")+" "+_("DEPRECATED");no;
+;SUB_TOD_TIME;1;(TOD, TIME);TOD;_("Time-of-day subtraction");no;
+;SUB;1;(TOD, TOD);TIME;_("Time-of-day subtraction")+" "+_("DEPRECATED");no;
+;SUB_TOD_TOD;1;(TOD, TOD);TIME;_("Time-of-day subtraction");no;
+;SUB;1;(DT, TIME);DT;_("Date and time subtraction")+" "+_("DEPRECATED");no;
+;SUB_DT_TIME;1;(DT, TIME);DT;_("Date and time subtraction");no;
+;SUB;1;(DT, DT);TIME;_("Date and time subtraction")+" "+_("DEPRECATED");no;
+;SUB_DT_TIME;1;(DT, DT);TIME;_("Date and time subtraction");no;
+;DIV;1;(TIME, ANY_NUM);TIME;_("Time division")+" "+_("DEPRECATED");no;
+;DIVTIME;1;(TIME, ANY_NUM);TIME;_("Time division");no;
+_("Bit-shift");SHL;1;(ANY_BIT, N);ANY_BIT;_("Shift left");no;
+;SHR;1;(ANY_BIT, N);ANY_BIT;_("Shift right");no;
+;ROR;1;(ANY_NBIT, N);ANY_NBIT;_("Rotate right");no;
+;ROL;1;(ANY_NBIT, N);ANY_NBIT;_("Rotate left");no;
+_("Bitwise");AND;1;(ANY_BIT, ANY_BIT);ANY_BIT;_("Bitwise AND");yes;
+;OR;1;(ANY_BIT, ANY_BIT);ANY_BIT;_("Bitwise OR");yes;
+;XOR;1;(ANY_BIT, ANY_BIT);ANY_BIT;_("Bitwise XOR");yes;
+;NOT;1;(ANY_BIT);ANY_BIT;_("Bitwise inverting");no;
+_("Selection");SEL;0;(G, ANY, ANY);ANY;_("Binary selection (1 of 2)");no;
+;MAX;1;(ANY, ANY);ANY;_("Maximum");yes;
+;MIN;1;(ANY, ANY);ANY;_("Minimum");yes;
+;LIMIT;1;(MN, ANY, MX);ANY;_("Limitation");no;
+;MUX;0;(K, ANY, ANY);ANY;_("Multiplexer (select 1 of N)");yes;
+_("Comparison");GT;1;(ANY, ANY);BOOL;_("Greater than");yes;
+;GE;1;(ANY, ANY);BOOL;_("Greater than or equal to");yes;
+;EQ;1;(ANY, ANY);BOOL;_("Equal to");yes;
+;LT;1;(ANY, ANY);BOOL;_("Less than");yes;
+;LE;1;(ANY, ANY);BOOL;_("Less than or equal to");yes;
+;NE;1;(ANY, ANY);BOOL;_("Not equal to");no;
+_("Character string");LEN;1;(STRING);INT;_("Length of string");no;
+;LEFT;1;(STRING, L);STRING;_("string left of");no;
+;RIGHT;1;(STRING, L);STRING;_("string right of");no;
+;MID;1;(STRING, L, P);STRING;_("string from the middle");no;
+;CONCAT;1;(STRING, STRING);STRING;_("Concatenation");yes;
+;CONCAT_DAT_TOD;1;(DATE, TOD);DT;_("Time concatenation");no;
+;INSERT;1;(STRING, STRING, P);STRING;_("Insertion (into)");no;
+;DELETE;1;(STRING, L, P);STRING;_("Deletion (within)");no;
+;REPLACE;1;(STRING, STRING, L, P);STRING;_("Replacement (within)");no;
+;FIND;1;(STRING, STRING);INT;_("Find position");no;
--- a/plcopen/structures.py	Mon Jan 27 14:45:12 2014 +0100
+++ b/plcopen/structures.py	Tue Jan 28 16:24:40 2014 +0100
@@ -22,67 +22,37 @@
 #License along with this library; if not, write to the Free Software
 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
-import string, os, sys, re
+import string, re
 from plcopen import LoadProject
 from collections import OrderedDict
-
-LANGUAGES = ["IL","ST","FBD","LD","SFC"]
-
-LOCATIONDATATYPES = {"X" : ["BOOL"],
-                     "B" : ["SINT", "USINT", "BYTE", "STRING"],
-                     "W" : ["INT", "UINT", "WORD", "WSTRING"],
-                     "D" : ["DINT", "UDINT", "REAL", "DWORD"],
-                     "L" : ["LINT", "ULINT", "LREAL", "LWORD"]} 
-
-_ = lambda x:x
-
-#-------------------------------------------------------------------------------
-#                        Function Block Types definitions
-#-------------------------------------------------------------------------------
-
-ScriptDirectory = os.path.split(os.path.realpath(__file__))[0]
-
-StdBlockLibrary, error = LoadProject(
-    os.path.join(ScriptDirectory, "Standard_Function_Blocks.xml"))
-AddnlBlockLibrary, error = LoadProject(
-    os.path.join(ScriptDirectory, "Additional_Function_Blocks.xml"))
-
-StdBlockComments = {
-    "SR": _("SR bistable\nThe SR bistable is a latch where the Set dominates."),
-    "RS": _("RS bistable\nThe RS bistable is a latch where the Reset dominates."),
-    "SEMA": _("Semaphore\nThe semaphore provides a mechanism to allow software elements mutually exclusive access to certain ressources."),
-    "R_TRIG": _("Rising edge detector\nThe output produces a single pulse when a rising edge is detected."),
-    "F_TRIG": _("Falling edge detector\nThe output produces a single pulse when a falling edge is detected."),
-    "CTU": _("Up-counter\nThe up-counter can be used to signal when a count has reached a maximum value."),
-    "CTD": _("Down-counter\nThe down-counter can be used to signal when a count has reached zero, on counting down from a preset value."),
-    "CTUD": _("Up-down counter\nThe up-down counter has two inputs CU and CD. It can be used to both count up on one input and down on the other."),
-    "TP": _("Pulse timer\nThe pulse timer can be used to generate output pulses of a given time duration."),
-    "TON": _("On-delay timer\nThe on-delay timer can be used to delay setting an output true, for fixed period after an input becomes true."),
-    "TOF": _("Off-delay timer\nThe off-delay timer can be used to delay setting an output false, for fixed period after input goes false."),
-    "RTC": _("Real time clock\nThe real time clock has many uses including time stamping, setting dates and times of day in batch reports, in alarm messages and so on."),
-    "INTEGRAL": _("Integral\nThe integral function block integrates the value of input XIN over time."),
-    "DERIVATIVE": _("Derivative\nThe derivative function block produces an output XOUT proportional to the rate of change of the input XIN."),
-    "PID": _("PID\nThe PID (proportional, Integral, Derivative) function block provides the classical three term controller for closed loop control."),
-    "RAMP": _("Ramp\nThe RAMP function block is modelled on example given in the standard."),
-    "HYSTERESIS": _("Hysteresis\nThe hysteresis function block provides a hysteresis boolean output driven by the difference of two floating point (REAL) inputs XIN1 and XIN2."),
-}
-
-for block_type in ["CTU", "CTD", "CTUD"]:
-    for return_type in ["DINT", "LINT", "UDINT", "ULINT"]:
-        StdBlockComments["%s_%s" % (block_type, return_type)] = StdBlockComments[block_type]
-
-def GetBlockInfos(pou):
-    infos = pou.getblockInfos()
-    infos["comment"] = StdBlockComments[infos["name"]]
-    infos["inputs"] = [
-        (var_name, var_type, "rising")
-        if var_name in ["CU", "CD"]
-        else (var_name, var_type, var_modifier)
-        for var_name, var_type, var_modifier in infos["inputs"]]
-    return infos
-
-"""
-Ordored list of common Function Blocks defined in the IEC 61131-3
+from definitions import *
+
+TypeHierarchy = dict(TypeHierarchy_list)
+
+"""
+returns true if the given data type is the same that "reference" meta-type or one of its types.
+"""
+def IsOfType(type, reference):
+    if reference is None:
+        return True
+    elif type == reference:
+        return True
+    else:
+        parent_type = TypeHierarchy[type]
+        if parent_type is not None:
+            return IsOfType(parent_type, reference)
+    return False
+
+"""
+returns list of all types that correspont to the ANY* meta type
+"""
+def GetSubTypes(type):
+    return [typename for typename, parenttype in TypeHierarchy.items() if not typename.startswith("ANY") and IsOfType(typename, type)]
+
+DataTypeRange = dict(DataTypeRange_list)
+
+"""
+Ordered list of common Function Blocks defined in the IEC 61131-3
 Each block have this attributes:
     - "name" : The block name
     - "type" : The block type. It can be "function", "functionBlock" or "program"
@@ -97,96 +67,11 @@
     - The default modifier which can be "none", "negated", "rising" or "falling"
 """
 
-StdBlckLst = [{"name" : _("Standard function blocks"), "list":
-               [GetBlockInfos(pou) for pou in StdBlockLibrary.getpous()]},
-              {"name" : _("Additional function blocks"), "list":
-               [GetBlockInfos(pou) for pou in AddnlBlockLibrary.getpous()]},
-             ]
-
-
-#-------------------------------------------------------------------------------
-#                           Data Types definitions
-#-------------------------------------------------------------------------------
-
-"""
-Ordored list of common data types defined in the IEC 61131-3
-Each type is associated to his direct parent type. It defines then a hierarchy
-between type that permits to make a comparison of two types
-"""
-TypeHierarchy_list = [
-    ("ANY", None),
-    ("ANY_DERIVED", "ANY"),
-    ("ANY_ELEMENTARY", "ANY"),
-    ("ANY_MAGNITUDE", "ANY_ELEMENTARY"),
-    ("ANY_BIT", "ANY_ELEMENTARY"),
-    ("ANY_NBIT", "ANY_BIT"),
-    ("ANY_STRING", "ANY_ELEMENTARY"),
-    ("ANY_DATE", "ANY_ELEMENTARY"),
-    ("ANY_NUM", "ANY_MAGNITUDE"),
-    ("ANY_REAL", "ANY_NUM"),
-    ("ANY_INT", "ANY_NUM"),
-    ("ANY_SINT", "ANY_INT"),
-    ("ANY_UINT", "ANY_INT"),
-    ("BOOL", "ANY_BIT"),
-    ("SINT", "ANY_SINT"),
-    ("INT", "ANY_SINT"),
-    ("DINT", "ANY_SINT"),
-    ("LINT", "ANY_SINT"),
-    ("USINT", "ANY_UINT"),
-    ("UINT", "ANY_UINT"),
-    ("UDINT", "ANY_UINT"),
-    ("ULINT", "ANY_UINT"),
-    ("REAL", "ANY_REAL"),
-    ("LREAL", "ANY_REAL"),
-    ("TIME", "ANY_MAGNITUDE"),
-    ("DATE", "ANY_DATE"),
-    ("TOD", "ANY_DATE"),
-    ("DT", "ANY_DATE"),
-    ("STRING", "ANY_STRING"),
-    ("BYTE", "ANY_NBIT"),
-    ("WORD", "ANY_NBIT"),
-    ("DWORD", "ANY_NBIT"),
-    ("LWORD", "ANY_NBIT")
-    #("WSTRING", "ANY_STRING") # TODO
-]
-
-TypeHierarchy = dict(TypeHierarchy_list)
-
-"""
-returns true if the given data type is the same that "reference" meta-type or one of its types.
-"""
-def IsOfType(type, reference):
-    if reference is None:
-        return True
-    elif type == reference:
-        return True
-    else:
-        parent_type = TypeHierarchy[type]
-        if parent_type is not None:
-            return IsOfType(parent_type, reference)
-    return False
-
-"""
-returns list of all types that correspont to the ANY* meta type
-"""
-def GetSubTypes(type):
-    return [typename for typename, parenttype in TypeHierarchy.items() if not typename.startswith("ANY") and IsOfType(typename, type)]
-
-
-DataTypeRange_list = [
-    ("SINT", (-2**7, 2**7 - 1)),
-    ("INT", (-2**15, 2**15 - 1)),
-    ("DINT", (-2**31, 2**31 - 1)),
-    ("LINT", (-2**31, 2**31 - 1)),
-    ("USINT", (0, 2**8 - 1)),
-    ("UINT", (0, 2**16 - 1)),
-    ("UDINT", (0, 2**31 - 1)),
-    ("ULINT", (0, 2**31 - 1))
-]
-
-DataTypeRange = dict(DataTypeRange_list)
-
-
+StdBlckLibs = {libname : LoadProject(tc6fname)[0]
+             for libname, tc6fname in StdTC6Libs}
+StdBlckLst = [{"name" : libname, "list":
+               [GetBlockInfos(pous) for pous in lib.getpous()]}
+             for libname, lib in StdBlckLibs.iteritems()]
 
 #-------------------------------------------------------------------------------
 #                             Test identifier
@@ -259,64 +144,6 @@
     return params
 
 
-ANY_TO_ANY_LIST=[
-        # simple type conv are let as C cast
-        (("ANY_INT","ANY_BIT"),("ANY_NUM","ANY_BIT"), ("return_type", "__move_", "IN_type")),
-        (("ANY_REAL",),("ANY_REAL",), ("return_type", "__move_", "IN_type")),
-        # REAL_TO_INT
-        (("ANY_REAL",),("ANY_SINT",), ("return_type", "__real_to_sint", None)),
-        (("ANY_REAL",),("ANY_UINT",), ("return_type", "__real_to_uint", None)),
-        (("ANY_REAL",),("ANY_BIT",), ("return_type", "__real_to_bit", None)),
-        # TO_TIME
-        (("ANY_INT","ANY_BIT"),("ANY_DATE","TIME"), ("return_type", "__int_to_time", None)),
-        (("ANY_REAL",),("ANY_DATE","TIME"), ("return_type", "__real_to_time", None)),
-        (("ANY_STRING",), ("ANY_DATE","TIME"), ("return_type", "__string_to_time", None)),
-        # FROM_TIME
-        (("ANY_DATE","TIME"), ("ANY_REAL",), ("return_type", "__time_to_real", None)),
-        (("ANY_DATE","TIME"), ("ANY_INT","ANY_NBIT"), ("return_type", "__time_to_int", None)),
-        (("TIME",), ("ANY_STRING",), ("return_type", "__time_to_string", None)),
-        (("DATE",), ("ANY_STRING",), ("return_type", "__date_to_string", None)),
-        (("TOD",), ("ANY_STRING",), ("return_type", "__tod_to_string", None)),
-        (("DT",), ("ANY_STRING",), ("return_type", "__dt_to_string", None)),
-        # TO_STRING
-        (("BOOL",), ("ANY_STRING",), ("return_type", "__bool_to_string", None)),
-        (("ANY_BIT",), ("ANY_STRING",), ("return_type", "__bit_to_string", None)),
-        (("ANY_REAL",), ("ANY_STRING",), ("return_type", "__real_to_string", None)),
-        (("ANY_SINT",), ("ANY_STRING",), ("return_type", "__sint_to_string", None)),
-        (("ANY_UINT",), ("ANY_STRING",), ("return_type", "__uint_to_string", None)),
-        # FROM_STRING
-        (("ANY_STRING",), ("BOOL",), ("return_type", "__string_to_bool", None)),
-        (("ANY_STRING",), ("ANY_BIT",), ("return_type", "__string_to_bit", None)),
-        (("ANY_STRING",), ("ANY_SINT",), ("return_type", "__string_to_sint", None)),
-        (("ANY_STRING",), ("ANY_UINT",), ("return_type", "__string_to_uint", None)),
-        (("ANY_STRING",), ("ANY_REAL",), ("return_type", "__string_to_real", None))]
-
-
-BCD_TO_ANY_LIST=[
-        (("BYTE",),("USINT",), ("return_type", "__bcd_to_uint", None)),
-        (("WORD",),("UINT",), ("return_type", "__bcd_to_uint", None)),
-        (("DWORD",),("UDINT",), ("return_type", "__bcd_to_uint", None)),
-        (("LWORD",),("ULINT",), ("return_type", "__bcd_to_uint", None))]
-
-
-ANY_TO_BCD_LIST=[
-        (("USINT",),("BYTE",), ("return_type", "__uint_to_bcd", None)),
-        (("UINT",),("WORD",), ("return_type", "__uint_to_bcd", None)),
-        (("UDINT",),("DWORD",), ("return_type", "__uint_to_bcd", None)),
-        (("ULINT",),("LWORD",), ("return_type", "__uint_to_bcd", None))]
-
-
-def ANY_TO_ANY_FORMAT_GEN(any_to_any_list, fdecl):
-
-    for (InTypes, OutTypes, Format) in any_to_any_list:
-        outs = reduce(lambda a,b: a or b, map(lambda testtype : IsOfType(fdecl["outputs"][0][1],testtype), OutTypes))
-        inps = reduce(lambda a,b: a or b, map(lambda testtype : IsOfType(fdecl["inputs"][0][1],testtype), InTypes))
-        if inps and outs and fdecl["outputs"][0][1] != fdecl["inputs"][0][1]:
-             return Format
-    
-    return None
-
-
 """
 Returns this kind of declaration for all standard functions
 
@@ -403,11 +230,24 @@
                             funcdeclout =  funcdeclin
                         Function_decl["name"] = funcdeclout
 
-
-                        fdecl = Function_decl
-                        res = eval(Function_decl["python_eval_c_code_format"])
-
-                        if res != None :
+                        # apply filter given in "filter" column
+                        filter_name = Function_decl["filter"]
+                        store = True
+                        for (InTypes, OutTypes) in ANY_TO_ANY_FILTERS.get(filter_name,[]):
+                            outs = reduce(lambda a,b: a or b, 
+                                       map(lambda testtype : IsOfType(
+                                           Function_decl["outputs"][0][1],
+                                           testtype), OutTypes))
+                            inps = reduce(lambda a,b: a or b,
+                                       map(lambda testtype : IsOfType(
+                                           Function_decl["inputs"][0][1],
+                                           testtype), InTypes))
+                            if inps and outs and Function_decl["outputs"][0][1] != Function_decl["inputs"][0][1]:
+                                store = True
+                                break
+                            else:
+                                store = False
+                        if store :
                             # create the copy of decl dict to be appended to section
                             Function_decl_copy = Function_decl.copy()
                             Current_section["list"].append(Function_decl_copy)
@@ -416,9 +256,7 @@
     
     return Standard_Functions_Decl
 
-std_decl = get_standard_funtions(csv_file_to_table(open(os.path.join(ScriptDirectory,"iec_std.csv"))))#, True)
-
-StdBlckLst.extend(std_decl)
+StdBlckLst.extend(get_standard_funtions(csv_file_to_table(open(StdFuncsCSV))))
 
 # Dictionary to speedup block type fetching by name
 StdBlckDct = OrderedDict()
@@ -440,7 +278,6 @@
 #                            Languages Keywords
 #-------------------------------------------------------------------------------
 
-
 # Keywords for Pou Declaration
 POU_BLOCK_START_KEYWORDS = ["FUNCTION", "FUNCTION_BLOCK", "PROGRAM"]
 POU_BLOCK_END_KEYWORDS = ["END_FUNCTION", "END_FUNCTION_BLOCK", "END_PROGRAM"]
@@ -502,3 +339,4 @@
     for keywords in keywords_list:
         all_keywords.extend([keyword for keyword in keywords if keyword not in all_keywords])
 
+