fix bugs, get more bugs

This commit is contained in:
Michael Becker 2024-10-10 08:10:30 -04:00
parent a18167f13f
commit a40a8b3685
25 changed files with 192363 additions and 457 deletions

192237
mocha-common/buildlog Normal file

File diff suppressed because one or more lines are too long

View File

@ -32,6 +32,7 @@ class Yaml2Mcl:
args = sys.argv[1:] args = sys.argv[1:]
# args = [ '-o', '/tmp/net.alcetech.Mocha.System.mcl', '/home/beckermj/Documents/Projects/mochapowered/mocha-dotnet/mocha-common/mocha-common/data/libraries/yaml/net.alcetech.Mocha.System' ] # args = [ '-o', '/tmp/net.alcetech.Mocha.System.mcl', '/home/beckermj/Documents/Projects/mochapowered/mocha-dotnet/mocha-common/mocha-common/data/libraries/yaml/net.alcetech.Mocha.System' ]
# args = [ "--reference", "/home/beckermj/Documents/Projects/mochapowered/mocha-dotnet/mocha-common/mocha-common/output/net.alcetech.Mocha.System.mcl", '-o', '/tmp/net.alcetech.Mocha.Web.mcl', '/home/beckermj/Documents/Projects/mochapowered/mocha-dotnet/mocha-common/mocha-common/data/libraries/yaml/net.alcetech.Mocha.Web' ]
# !! FIXME !! the instance key is probably not in the cache because the 'class' template is not loaded from the YAML so it doesn't know what to do # !! FIXME !! the instance key is probably not in the cache because the 'class' template is not loaded from the YAML so it doesn't know what to do
@ -96,6 +97,11 @@ class Yaml2Mcl:
for inst in om.get_instances(): for inst in om.get_instances():
manager.add_instance_ref(inst.get_class_global_identifier(), inst.get_instance_global_identifier(), inst.get_class_index(), inst.get_instance_index()) manager.add_instance_ref(inst.get_class_global_identifier(), inst.get_instance_global_identifier(), inst.get_class_index(), inst.get_instance_index())
tdfs = om.get_template_definitions()
for key in tdfs:
yl.register_template(key, tdfs[key], True)
for filename in filenames: for filename in filenames:

View File

@ -1,417 +0,0 @@
class UUIDParseFailureKind:
FORMAT = 2
class UUIDParseNumbers:
NOSPACE = 2
class UUIDParseResult:
def __init__(self):
self.parsedGuid = Guid()
self.kind = None
self.message = None
def setFailure(self, kind, message):
self.kind = kind
self.message = message
class Guid:
__urand = None
def __init__(self):
if Guid.__urand is None:
Guid.__urand = open("/dev/urandom", "rb")
self.__a = 0
self.__b = 0
self.__c = 0
self.__d = 0
self.__e = 0
self.__f = 0
self.__g = 0
self.__h = 0
self.__i = 0
self.__j = 0
self.__k = 0
@staticmethod
def __stringToInt(guidString : str, parsePos : int, requiredLength : int, flags : int, result : int, parseResult):
parseWhat = guidString[parsePos:(parsePos+requiredLength)]
result = int(parseWhat, 16)
parsePos += requiredLength
return (parsePos, result)
@staticmethod
def fromBytes(b : bytes):
guid = Guid()
guid.__a = (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | b[0]
guid.__b = (b[5] << 8) | b[4]
guid.__c = ((b[7] << 8) | b[6])
guid.__d = b[8]
guid.__e = b[9]
guid.__f = b[10]
guid.__g = b[11]
guid.__h = b[12]
guid.__i = b[13]
guid.__j = b[14]
guid.__k = b[15]
return guid
@staticmethod
def __tryParseGuidWithDashes(guidString : str) -> UUIDParseResult:
result = UUIDParseResult()
print (guidString)
if guidString == "":
return result
guidString = guidString.replace("{", "").replace("}", "").replace("-", "")
import codecs
try:
myBytes = codecs.decode(guidString, 'hex')
except:
return result
guidBytes = [ myBytes[3], myBytes[2], myBytes[1], myBytes[0], myBytes[5], myBytes[4], myBytes[7], myBytes[6], myBytes[8],
myBytes[9], myBytes[10], myBytes[11], myBytes[12], myBytes[13], myBytes[14], myBytes[15] ]
result.parsedGuid = Guid.fromBytes(guidBytes)
return result
"""
startPos = 0
temp = 0
templ = 0
currentPos = 0
result = UUIDParseResult()
hasDashes = True
if (len(guidString) < 1):
print(guidString)
result.setFailure(UUIDParseFailureKind.FORMAT, "Format_GuidInvLen[?]")
return result
# check to see that it's the proper length
if guidString[0] == '{':
if len(guidString) != 38 or guidString[37] != '}':
print(guidString)
result.setFailure(UUIDParseFailureKind.FORMAT, "Format_GuidInvLen[38]")
return result
startPos = 1
elif guidString[0] == '(':
if len(guidString) != 38 or guidString[37] != ')':
print(guidString)
result.setFailure(UUIDParseFailureKind.FORMAT, "Format_GuidInvLen[38]")
return result
startPos = 1
elif len(guidString) != 36:
if len(guidString) != 32:
print(guidString)
result.setFailure(UUIDParseFailureKind.FORMAT, "Format_GuidInvLen[36]")
return result
else:
hasDashes = False
if hasDashes:
if (guidString[8 + startPos] != '-' or
guidString[13 + startPos] != '-' or
guidString[18 + startPos] != '-' or
guidString[23 + startPos] != '-'):
result.setFailure(UUIDParseFailureKind.FORMAT, "Format_GuidDashes")
return result
currentPos = startPos
(parsePos, temp) = Guid.__stringToInt(guidString, currentPos, 8, UUIDParseNumbers.NOSPACE, temp, result)
result.parsedGuid.__a = temp
currentPos = parsePos
if hasDashes:
currentPos = currentPos + 1; # Increment past the '-';
(parsePos, temp) = Guid.__stringToInt(guidString, currentPos, 4, UUIDParseNumbers.NOSPACE, temp, result)
result.parsedGuid.__b = temp
currentPos = parsePos
if hasDashes:
currentPos = currentPos + 1 # Increment past the '-';
(parsePos, temp) = Guid.__stringToInt(guidString, currentPos, 4, UUIDParseNumbers.NOSPACE, temp, result)
result.parsedGuid.__c = temp
currentPos = parsePos
if hasDashes:
currentPos = currentPos + 1 # Increment past the '-';
(parsePos, temp) = Guid.__stringToInt(guidString, currentPos, 4, UUIDParseNumbers.NOSPACE, temp, result)
result.parsedGuid.__d = temp >> 8
result.parsedGuid.__e = temp - (temp >> 8)
currentPos = parsePos
if hasDashes:
currentPos = currentPos + 1 # Increment past the '-';
startPos = currentPos
(parsePos, templ) = Guid.__stringToInt(guidString, currentPos, 8, UUIDParseNumbers.NOSPACE, templ, result)
currentPos = parsePos
(parsePos, temp2) = Guid.__stringToInt(guidString, currentPos, 4, UUIDParseNumbers.NOSPACE, templ, result)
# /*
# if ($currentPos - $startPos != 12) {
# $result->setFailure(UUIDParseFailureKind::FORMAT, "Format_GuidInvLen(*)")
# return $result;
# }
# */
result.parsedGuid.__j = temp2 >> 8
result.parsedGuid.__k = temp2 - (temp2 >> 8)
temp = templ
result.parsedGuid.__f = temp >> 24
result.parsedGuid.__g = (temp >> 16) - (temp >> 24)
result.parsedGuid.__h = (temp >> 8) - (temp >> 16)
result.parsedGuid.__i = temp - (temp >> 8)
return result
"""
def parse(value : str):
if value is None:
return None
result = Guid.__tryParseGuidWithDashes(value)
return result.parsedGuid
def __eq__(self, other):
# /*
# if (
# $uuid->clock_seq_hi_and_reserved == self.clock_seq_hi_and_reserved
# && $uuid->node == self.node
# && $uuid->time_hi_and_version == self.time_hi_and_version
# && $uuid->time_low == self.time_low
# && $uuid->time_mid == self.time_mid
# )
# {
# return true;
# }
# */
return (
other.__a == self.__a
and other.__b == self.__b
and other.__c == self.__c
and other.__d == self.__d
and other.__e == self.__e
and other.__f == self.__f
and other.__g == self.__g
and other.__h == self.__h
and other.__i == self.__i
and other.__j == self.__j
and other.__k == self.__k
)
@staticmethod
def __init_bits():
__pr_bits = False
if Guid.__urand is not None:
__pr_bits += Guid.__urand.read(16)
if not self.__pr_bits:
fp = open ( '/dev/urandom', 'rb' )
if fp is not False:
__pr_bits += fp.read(16)
fp.close()
else:
# If /dev/urandom isn't available (eg: in non-unix systems), use mt_rand().
__pr_bits = ""
for cnt in range(0, 16):
__pr_bits += chr ( __mt_rand ( 0, 255 ) )
return __pr_bits
"""
@brief Generates a Universally Unique IDentifier, version 4.
This function generates a truly random UUID. The built in CakePHP String::uuid() function
is not cryptographically secure. You should uses this function instead.
@see http://tools.ietf.org/html/rfc4122#section-4.4
@see http://en.wikipedia.org/wiki/UUID
@return UUID A UUID, made up of 32 hex digits and 4 hyphens.
"""
@staticmethod
def generate():
uuid = Guid()
__pr_bits = Guid.__init_bits()
uuid.__a = (int(pr_bits[3]) << 24) | (int(pr_bits[2]) << 16) | (int(pr_bits[1]) << 8) | pr_bits[0]
uuid.__b = ((int(pr_bits[5]) << 8) | pr_bits[4])
uuid.__c = ((int(pr_bits[7]) << 8) | pr_bits[6])
uuid.__d = pr_bits[8]
uuid.__e = pr_bits[9]
uuid.__f = pr_bits[10]
uuid.__g = pr_bits[11]
uuid.__h = pr_bits[12]
uuid.__i = pr_bits[13]
uuid.__j = pr_bits[14]
uuid.__k = pr_bits[15]
return uuid
@staticmethod
def __hexToChar(a : int) -> str:
a = a & 0xf
v = 0
if a > 9:
v = a - 10 + 0x61
else:
v = a + 0x30
return chr(v)
@staticmethod
def __hexsToChars(a : int, b : int, hex : bool = False):
guidChars = ""
if hex:
guidChars = "0x"
guidChars += Guid.__hexToChar(a >> 4)
guidChars += Guid.__hexToChar(a)
if hex:
guidChars += ",0x"
guidChars += Guid.__hexToChar(b >> 4)
guidChars += Guid.__hexToChar(b)
return guidChars
# public function __toString()
# {
# }
# public function __toStringFormat($includeDashes = true, $prefix = "{", $suffix = "}")
# {
# $guidChars = $prefix;
# $guidChars += Guid.__hexsToChars(self._a >> 24, self._a >> 16)
# $guidChars += Guid.__hexsToChars(self._a >> 8, self._a)
# if ($includeDashes) $guidChars += '-';
# $guidChars += Guid.__hexsToChars(self._b >> 8, self._b)
# if ($includeDashes) $guidChars += '-';
# $guidChars += Guid.__hexsToChars(self._c >> 8, self._c)
# if ($includeDashes) $guidChars += '-';
# $guidChars += Guid.__hexsToChars(self._d, self._e)
# if ($includeDashes) $guidChars += '-';
# $guidChars += Guid.__hexsToChars(self._f, self._g)
# $guidChars += Guid.__hexsToChars(self._h, self._i)
# $guidChars += Guid.__hexsToChars(self._j, self._k)
# $guidChars += $suffix;
# return $guidChars;
# }
def format(input : str):
output = input
output = output[0:8] + "-" + output[8:(8+4)] + "-" + output[12:12+4] + "-" + output[16:16+4] + "-" + output[20:]
return "{" + output + "}"
def strip(self):
guidChars = ""
guidChars += Guid.__hexsToChars(self.__a >> 24, self.__a >> 16)
guidChars += Guid.__hexsToChars(self.__a >> 8, self.__a)
guidChars += Guid.__hexsToChars(self.__b >> 8, self.__b)
guidChars += Guid.__hexsToChars(self.__c >> 8, self.__c)
guidChars += Guid.__hexsToChars(self.__d, self.__e)
guidChars += Guid.__hexsToChars(self.__f, self.__g)
guidChars += Guid.__hexsToChars(self.__h, self.__i)
guidChars += Guid.__hexsToChars(self.__j, self.__k)
return guidChars.lower()
def __str__(self):
# //return self.format(strtoupper( sprintf ( '%08s%04s%04x%04x%012s', self.time_low, self.time_mid, self.time_hi_and_version, self.clock_seq_hi_and_reserved, self.node ) ))
dash = True
guidChars = "{"
guidChars += Guid.__hexsToChars(self.__a >> 24, self.__a >> 16)
guidChars += Guid.__hexsToChars(self.__a >> 8, self.__a)
if (dash):
guidChars += '-'
guidChars += Guid.__hexsToChars(self.__b >> 8, self.__b)
if (dash):
guidChars += '-'
guidChars += Guid.__hexsToChars(self.__c >> 8, self.__c)
if (dash):
guidChars += '-'
guidChars += Guid.__hexsToChars(self.__d, self.__e)
if (dash):
guidChars += '-'
guidChars += Guid.__hexsToChars(self.__f, self.__g)
guidChars += Guid.__hexsToChars(self.__h, self.__i)
guidChars += Guid.__hexsToChars(self.__j, self.__k)
guidChars += "}"
return guidChars.lower()
@staticmethod
def create():
from uuid import uuid4
u = uuid4()
g = Guid.parse(str(u))
return g
def __key(self):
return (self.__a, self.__b, self.__c, self.__d, self.__e, self.__f, self.__g, self.__h, self.__i, self.__j, self.__k)
def __hash__(self):
return hash(self.__key())
def __eq__(self, other):
if isinstance(other, Guid):
return self.__key() == other.__key()
return NotImplemented
def to_bytes(self) -> bytes:
a = self.__a.to_bytes(4, 'little')
b = self.__b.to_bytes(2, 'little')
c = self.__c.to_bytes(2, 'little')
a0 = a[0]
a1 = a[1]
a2 = a[2]
a3 = a[3]
b0 = b[0]
b1 = b[1]
c0 = c[0]
c1 = c[1]
d = self.__d
e = self.__e
f = self.__f
g = self.__g
h = self.__h
i = self.__i
j = self.__j
k = self.__k
sss = [a0, a1, a2, a3, b0, b1, c0, c1, d, e, f, g, h, i, j, k]
return bytes(sss)

View File

@ -1,4 +1,4 @@
from .Guid import Guid from framework import Guid
""" """
Represents the Text Attribute `Name` Represents the Text Attribute `Name`

View File

@ -1,4 +1,4 @@
from .Guid import Guid from framework import Guid
IDC_SourceDefinition = Guid.parse("{5d0b2f03-4886-4ba6-ac3c-8f9612963fa6}") IDC_SourceDefinition = Guid.parse("{5d0b2f03-4886-4ba6-ac3c-8f9612963fa6}")
IDC_EntityDefinition = Guid.parse("{15ffa529-6aab-4f1f-8720-f2534951b045}") IDC_EntityDefinition = Guid.parse("{15ffa529-6aab-4f1f-8720-f2534951b045}")

View File

@ -1,3 +1,3 @@
from .Guid import Guid from framework import Guid
IDR_Instance__has__Source_Definition = Guid.parse("{57cbc351-0428-47e6-a6db-445e4503abab}") IDR_Instance__has__Source_Definition = Guid.parse("{57cbc351-0428-47e6-a6db-445e4503abab}")

View File

@ -1,18 +0,0 @@
# Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
#
# This file is part of yaml2mcl.
#
# yaml2mcl 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 3 of the License, or
# (at your option) any later version.
#
# yaml2mcl 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 yaml2mcl. If not, see <https://www.gnu.org/licenses/>.
from .Guid import Guid

View File

@ -1,5 +1,5 @@
from .manager.Normalization import Normalization from .manager.Normalization import Normalization
from ..core.Guid import Guid from framework import Guid
class InstanceCache: class InstanceCache:
@ -64,4 +64,7 @@ class InstanceCache:
self.dbids_gid[Normalization.normalize_uuid(gid.get_value())] = dbid self.dbids_gid[Normalization.normalize_uuid(gid.get_value())] = dbid
# self.dbids_idx[self.inst_indices[gid]] = dbid # self.dbids_idx[self.inst_indices[gid]] = dbid
def get_database_id_by_global_identifier(self, gid : Guid): def get_database_id_by_global_identifier(self, gid : Guid):
return self.dbids_gid[Normalization.normalize_uuid(gid.get_value())] return self.dbids_gid[Normalization.normalize_uuid(gid.get_value())]
def __len__(self):
return len(self.inst_guids)

View File

@ -15,7 +15,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with yaml2mcl. If not, see <https://www.gnu.org/licenses/>. # along with yaml2mcl. If not, see <https://www.gnu.org/licenses/>.
from ...core.Guid import Guid from framework import Guid
class GuidCache: class GuidCache:

View File

@ -10,7 +10,7 @@ from ..manager.operations.StoredProcedureOperation import StoredProcedureOperati
from .Normalization import Normalization from .Normalization import Normalization
from ...core.Guid import Guid from framework import Guid
from ...core.KnownClassGuids import IDC_EntityDefinition, IDC_SourceDefinition from ...core.KnownClassGuids import IDC_EntityDefinition, IDC_SourceDefinition
from ...core.KnownAttributeGuids import * from ...core.KnownAttributeGuids import *
from ...core.KnownRelationshipGuids import * from ...core.KnownRelationshipGuids import *
@ -72,14 +72,18 @@ class MochaLibraryManager:
if class_gid is not None and class_index is None: if class_gid is not None and class_index is None:
# print ("unknown class import") # print ("unknown class import")
if not instances.has_instance_by_global_identifier(class_gid): if not instances.has_instance_by_global_identifier(class_gid):
class_index = instances.get_next_instance_id(class_index) if not instance_refs.has_instance_by_global_identifier(class_gid):
print ("WARNING : UGLY HACK USED")
class_index = instances.get_next_instance_id(class_index)
else:
class_index = instance_refs.get_instance_key(class_gid)[1]
else: else:
class_index = instances.get_instance_key(class_gid)[1] class_index = instances.get_instance_key(class_gid)[1]
if inst_index is None: if inst_index is None:
inst_index = instances.get_next_instance_id(class_index) inst_index = instances.get_next_instance_id(class_index)
instances.add_instance((1, inst_index), inst_gid) instances.add_instance((class_index, inst_index), inst_gid)
# print ("class_gid = " + class_gid) # print ("class_gid = " + class_gid)
# print ("inst_gid = " + inst_gid + " (" + str(1) + "$" + str(inst_index) + ")") # print ("inst_gid = " + inst_gid + " (" + str(1) + "$" + str(inst_index) + ")")
@ -95,14 +99,22 @@ class MochaLibraryManager:
if instances.has_instance_by_global_identifier(class_gid): if instances.has_instance_by_global_identifier(class_gid):
class_index = instances.get_instance_key(class_gid)[1] class_index = instances.get_instance_key(class_gid)[1]
else: else:
class_index = instances.get_next_instance_id(1) if not instance_refs.has_instance_by_global_identifier(class_gid):
print ("WARNING : UGLY HACK USED")
class_index = instances.get_next_instance_id(1)
else:
class_index = instance_refs.get_instance_key(class_gid)[1]
if inst_index is None: if inst_index is None:
# we need to know the instance index as well # we need to know the instance index as well
if instances.has_instance_by_global_identifier(inst_gid): if instances.has_instance_by_global_identifier(inst_gid):
inst_index = instances.get_instance_key(inst_gid)[1] inst_index = instances.get_instance_key(inst_gid)[1]
else: else:
inst_index = instances.get_next_instance_id(class_index) if not instance_refs.has_instance_by_global_identifier(inst_gid):
print ("WARNING : UGLY HACK USED")
inst_index = instances.get_next_instance_id(class_index)
else:
inst_index = instances.get_instance_key(inst_gid)[1]
else: else:
print("error: not implemened class_gid is None or inst_gid is None") print("error: not implemened class_gid is None or inst_gid is None")
@ -280,6 +292,9 @@ class MochaLibraryManager:
if not inst_gid is None and not class_gid is None: if not inst_gid is None and not class_gid is None:
instance_ops.append(PrepareInstanceOperation(class_gid, inst_gid, class_index, inst_index)) instance_ops.append(PrepareInstanceOperation(class_gid, inst_gid, class_index, inst_index))
else:
print( "WARNING: class guid not found for " + str(class_index) + '$' + str(inst_index))
pass
self.process_instance_ops(instance_ops) self.process_instance_ops(instance_ops)

View File

@ -1,4 +1,4 @@
from ...core.Guid import Guid from framework import Guid
from .Normalization import Normalization from .Normalization import Normalization
class SQLExpression: class SQLExpression:

View File

@ -1,5 +1,5 @@
from .StoredProcedureOperation import StoredProcedureOperation from .StoredProcedureOperation import StoredProcedureOperation
from ....core.Guid import Guid from framework import Guid
from ..SQLParameter import SQLParameter from ..SQLParameter import SQLParameter
from ..SQLFunctionCall import SQLFunctionCall from ..SQLFunctionCall import SQLFunctionCall

View File

@ -1,5 +1,5 @@
from .StoredProcedureOperation import StoredProcedureOperation from .StoredProcedureOperation import StoredProcedureOperation
from ....core.Guid import Guid from framework import Guid
from ..SQLParameter import SQLParameter from ..SQLParameter import SQLParameter
from ..SQLFunctionCall import SQLFunctionCall from ..SQLFunctionCall import SQLFunctionCall

View File

@ -1,7 +1,7 @@
from .StoredProcedureOperation import StoredProcedureOperation from .StoredProcedureOperation import StoredProcedureOperation
from ..SQLParameter import SQLParameter from ..SQLParameter import SQLParameter
from ..SQLFunctionCall import SQLFunctionCall from ..SQLFunctionCall import SQLFunctionCall
from ....core.Guid import Guid from framework import Guid
class CreateClassOperation (StoredProcedureOperation): class CreateClassOperation (StoredProcedureOperation):

View File

@ -1,5 +1,5 @@
from .StoredProcedureOperation import StoredProcedureOperation from .StoredProcedureOperation import StoredProcedureOperation
from ....core.Guid import Guid from framework import Guid
from ..SQLParameter import SQLParameter from ..SQLParameter import SQLParameter
from ..SQLFunctionCall import SQLFunctionCall from ..SQLFunctionCall import SQLFunctionCall

View File

@ -1,5 +1,5 @@
from .StoredProcedureOperation import StoredProcedureOperation from .StoredProcedureOperation import StoredProcedureOperation
from ....core.Guid import Guid from framework import Guid
from ..SQLParameter import SQLParameter from ..SQLParameter import SQLParameter
from ..SQLFunctionCall import SQLFunctionCall from ..SQLFunctionCall import SQLFunctionCall

View File

@ -5,7 +5,7 @@ from MySQLdb.connections import Connection
from ..SQLExpression import SQLExpression from ..SQLExpression import SQLExpression
from ..SQLParameter import SQLParameter from ..SQLParameter import SQLParameter
from ..SQLFunctionCall import SQLFunctionCall from ..SQLFunctionCall import SQLFunctionCall
from ....core.Guid import Guid from framework import Guid
class StoredProcedureOperation (LibraryOperation): class StoredProcedureOperation (LibraryOperation):
def get_sp_name(self): def get_sp_name(self):

View File

@ -34,8 +34,17 @@ class GuidSection (Section):
Section.__init__(self, name, data, 16) Section.__init__(self, name, data, 16)
def write_data(self, f): def write_data(self, f):
i = 0
for guid in self.data: for guid in self.data:
f.write(guid.to_bytes()) if guid is not None:
f.write(guid.to_bytes())
else:
print("guid at " + str(i) + " is None")
from framework import Guid
f.write(Guid().to_bytes())
i += 1
class InstancesSection (Section): class InstancesSection (Section):
def __init__(self, name : str, data : list): def __init__(self, name : str, data : list):

View File

@ -15,7 +15,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with yaml2mcl. If not, see <https://www.gnu.org/licenses/>. # along with yaml2mcl. If not, see <https://www.gnu.org/licenses/>.
from mocha.core import Guid from framework import Guid
from .Section import Section from .Section import Section
class SectionFile: class SectionFile:

View File

@ -138,6 +138,38 @@ class McxDataFormat (DataFormat):
object_model.get_relationships().append(McxRelationship(isrc, irel, itgt)) object_model.get_relationships().append(McxRelationship(isrc, irel, itgt))
elif section_name == 'Templates':
print("mcx: reading templates")
r.get_stream().seek(offset)
sizes = [ ]
names = [ ]
datas = dict()
from editor.core.io import Endianness
r.set_endianness(endianness=Endianness.BIG)
for i in range(0, itemcount):
nameLen = r.read_int32()
dataLen = r.read_int32()
sizes.append((nameLen, dataLen))
for i in range(0, itemcount):
nameLen = sizes[i][0]
names.append(r.read_fixedstring(nameLen))
for i in range(0, itemcount):
import yaml
dataLen = sizes[i][1]
data = yaml.safe_load(r.read_fixedstring(dataLen))
name = names[i]
if "customTagName" in data:
name = data["customTagName"]
object_model.register_template_definition(name, data)
pass
def save_internal(self, object_model : ObjectModel, stream : FileIO): def save_internal(self, object_model : ObjectModel, stream : FileIO):

View File

@ -15,6 +15,8 @@ class McxObjectModel (ObjectModel):
self.__entityDefinitionsKeys = dict() self.__entityDefinitionsKeys = dict()
self.__entityDefinitionsValues = dict() self.__entityDefinitionsValues = dict()
self.template_definitions = dict()
def get_instances(self) -> list[McxInstance]: def get_instances(self) -> list[McxInstance]:
return self._instances return self._instances
@ -49,3 +51,8 @@ class McxObjectModel (ObjectModel):
return key in self.__entityDefinitionsValues return key in self.__entityDefinitionsValues
def has_entity_value(self, value : str): def has_entity_value(self, value : str):
return value in self.__entityDefinitionsKeys return value in self.__entityDefinitionsKeys
def get_template_definitions(self):
return self.template_definitions
def register_template_definition(self, key , value):
self.template_definitions[key] = value

View File

@ -1,5 +1,5 @@
from .LibraryParser import LibraryParser from .LibraryParser import LibraryParser
from ...core.Guid import Guid from framework import Guid
from .MochaSyntaxError import MochaSyntaxError from .MochaSyntaxError import MochaSyntaxError
class YAMLLibraryParser (LibraryParser): class YAMLLibraryParser (LibraryParser):
@ -10,6 +10,7 @@ class YAMLLibraryParser (LibraryParser):
# FIXME: these two are kind of the same thing; can we merge them? # FIXME: these two are kind of the same thing; can we merge them?
self.yamlIds = dict() self.yamlIds = dict()
self.templates = dict() self.templates = dict()
self.templates_from_reference = dict[bool]()
# these two are special reserved tagNames # these two are special reserved tagNames
# self.yamlIds["entityDefinitions"] = None # self.yamlIds["entityDefinitions"] = None
@ -195,8 +196,18 @@ class YAMLLibraryParser (LibraryParser):
template = self.yamlIds[key] template = self.yamlIds[key]
templateKey = key templateKey = key
return (elem[templateKey], templateKey, template) return (elem[templateKey], templateKey, template)
for key in self.templates:
if key in elem:
template = self.templates[key]
templateKey = key
return (elem[templateKey], templateKey, template)
return (None, None, None) # should never get here return (None, None, None) # should never get here
def register_template(self, key, value, from_reference : bool = False):
self.templates[key] = value
self.templates_from_reference[key] = from_reference
def load_instance(self, elem, elemParent = None): def load_instance(self, elem, elemParent = None):
@ -225,6 +236,7 @@ class YAMLLibraryParser (LibraryParser):
if "customTagName" in elem: if "customTagName" in elem:
customTagName = elem["customTagName"] customTagName = elem["customTagName"]
self.yamlIds[customTagName] = elem self.yamlIds[customTagName] = elem
self.templates[customTagName] = elem
print("registering customTagName '" + customTagName + "'") print("registering customTagName '" + customTagName + "'")
if "registerForTemplate" in elem or True: if "registerForTemplate" in elem or True:
@ -247,6 +259,10 @@ class YAMLLibraryParser (LibraryParser):
if key in template: if key in template:
classId = Guid.parse(self.manager.expand_entity_references(template[key])) classId = Guid.parse(self.manager.expand_entity_references(template[key]))
break break
for key in self.templates:
if key in template:
classId = Guid.parse(self.manager.expand_entity_references(template[key]))
break
if "index" in template: if "index" in template:
classIndex = template["index"] classIndex = template["index"]
@ -267,6 +283,11 @@ class YAMLLibraryParser (LibraryParser):
instanceId = Guid.parse(self.manager.expand_entity_references(elem[key])) instanceId = Guid.parse(self.manager.expand_entity_references(elem[key]))
creatorKey = key creatorKey = key
break break
for key in self.templates:
if key in elem:
instanceId = Guid.parse(self.manager.expand_entity_references(elem[key]))
creatorKey = key
break
index = None index = None
if "index" in elem: if "index" in elem:
@ -285,6 +306,7 @@ class YAMLLibraryParser (LibraryParser):
if instanceId is not None: if instanceId is not None:
self.manager.add_instance(classId, instanceId, classIndex, index) self.manager.add_instance(classId, instanceId, classIndex, index)
# !FIXME: this ads the instance, but it still doesn't appear in the instance list??
if creatorKey == 'class': #FIXME: remove this special-case behavior if creatorKey == 'class': #FIXME: remove this special-case behavior
print("creating class " + str(instanceId)) print("creating class " + str(instanceId))

View File

@ -3,6 +3,7 @@
instances: instances:
- instance: '&IDC_Class;' - instance: '&IDC_Class;'
templateOnly: yes templateOnly: yes
registerForTemplate: yes
customTagName: 'class' customTagName: 'class'
attributes: attributes:
- instance: '&IDA_Name;' - instance: '&IDA_Name;'

View File

@ -4,6 +4,7 @@
- instance: '&IDC_Class;' - instance: '&IDC_Class;'
templateOnly: yes templateOnly: yes
customTagName: 'class' customTagName: 'class'
registerForTemplate: yes
attributes: attributes:
- instance: '&IDA_Name;' - instance: '&IDA_Name;'
customTagName: 'name' customTagName: 'name'

View File

@ -20,6 +20,14 @@
name: 'Route URL' name: 'Route URL'
index: 438 index: 438
# none of the 'class' definitions are getting loaded
# because the 'class' customTagName is defined in net.alcetech.Mocha.System.mcl
# and the yaml2mcl compiler doesn't see it
# ... I believe we do actually store the YAML source in the MCL, at least during the linking process
# ... so we should be able to figure this one out!
# ! this is stopping work on the .NET Web server, as it requires net.alcetech.Mocha.Web.mcl to work
# ? this would also explain why our Instance IDs in Mocha.Web go bonkers
- class: '&IDC_Route;' - class: '&IDC_Route;'
name: Route name: Route
index: 434 index: 434