Skip to content

Commit

Permalink
Merge branch 'master' into development/actions-windows-fix
Browse files Browse the repository at this point in the history
  • Loading branch information
pwielders authored Oct 18, 2023
2 parents bb18beb + 7146fe5 commit 676594d
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 42 deletions.
30 changes: 22 additions & 8 deletions JsonGenerator/source/documentation_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def _TableObj(name, obj, parentName="", parent=None, prefix="", parentOptional=F

if name or prefix:
if "type" not in obj:
raise DocumentationError("missing 'type' for object %s" % (parentName + "/" + name))
raise DocumentationError("'%s': missing 'type' for this object" % (parentName + "/" + name))

row = (("<sup>" + italics("(optional)") + "</sup>" + " ") if optional else "")

Expand All @@ -127,6 +127,11 @@ def _TableObj(name, obj, parentName="", parent=None, prefix="", parentOptional=F
if optional and "default" in obj:
row += " (default: " + (italics("%s") % str(obj["default"]) + ")")

if obj["type"] == "number":
# correct number to integer
if ("float" not in obj or not obj["float"]) and ("example" not in obj or '.' not in str(obj["example"])):
obj["type"] = "integer"

MdRow([prefix, "opaque object" if obj.get("opaque") else obj["type"], row])

if obj["type"] == "object":
Expand Down Expand Up @@ -172,9 +177,18 @@ def ExampleObj(name, obj, root=False):

if obj_type == "string":
json_data += "{ }" if obj.get("opaque") else ('"%s"' % (default if default else "..."))
elif obj_type in ["integer", "number"]:
elif obj_type == "integer":
if default and not str(default).isnumeric():
raise DocumentationError("'%s': invalid example syntax for this integer type (see '%s')" % (name, default))

json_data += '%s' % (default if default else 0)
elif obj_type in ["float", "double"]:
elif obj_type == "number":
if default and not str(default).replace('.','').isnumeric():
raise DocumentationError("'%s': invalid example syntax for this numeric (floating-point) type (see '%s')" % (name, default))

if default and '.' not in str(default):
default = default * 1.0

json_data += '%s' % (default if default else 0.0)
elif obj_type == "boolean":
json_data += '%s' % str(default if default else False).lower()
Expand All @@ -192,7 +206,7 @@ def ExampleObj(name, obj, root=False):

def MethodDump(method, props, classname, section, is_notification=False, is_property=False, include=None):
method = (method.rsplit(".", 1)[1] if "." in method else method)
type = "property" if is_property else "event" if is_notification else "method"
type = "property" if is_property else "event" if is_notification else "method"

log.Info("Emitting documentation for %s '%s'..." % (type, method))

Expand Down Expand Up @@ -252,7 +266,7 @@ def MethodDump(method, props, classname, section, is_notification=False, is_prop

if "index" in props:
if "name" not in props["index"] or "example" not in props["index"]:
raise DocumentationError("in %s: index field needs 'name' and 'example' properties" % method)
raise DocumentationError("'%s': index field requires 'name' and 'example' properties" % method)

extra_paragraph = "> The *%s* argument shall be passed as the index to the property, e.g. *%s.1.%s@%s*.%s" % (
props["index"]["name"].lower(), classname, method, props["index"]["example"],
Expand All @@ -276,7 +290,7 @@ def MethodDump(method, props, classname, section, is_notification=False, is_prop
if is_notification:
if "id" in props:
if "name" not in props["id"] or "example" not in props["id"]:
raise DocumentationError("in %s: id field needs 'name' and 'example' properties" % method)
raise DocumentationError("'%s': id field needs 'name' and 'example' properties" % method)

MdParagraph("> The *%s* argument shall be passed within the designator, e.g. *%s.client.events.1*." %
(props["id"]["name"], props["id"]["example"]))
Expand Down Expand Up @@ -333,7 +347,7 @@ def MethodDump(method, props, classname, section, is_notification=False, is_prop
object_pairs_hook=OrderedDict), indent=2)
MdCode(jsonResponse, "json")
elif "noresult" not in props or not props["noresult"]:
raise DocumentationError("missing 'result' in %s" % method)
raise DocumentationError("'%s': missing 'result' in this method" % method)

if is_property:
MdHeader("Set Response", 4)
Expand Down Expand Up @@ -421,7 +435,7 @@ def MethodDump(method, props, classname, section, is_notification=False, is_prop
elif status == "production" or status == "prod":
rating = 3
else:
raise DocumentationError("invalid status")
raise DocumentationError("invalid status (see '%s')" % status)

plugin_class = None

Expand Down
2 changes: 1 addition & 1 deletion JsonGenerator/source/header_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ def ConvertType(var):
result = [ "integer", { "size": size, "signed": cppType.signed } ]
# Float
elif isinstance(cppType, CppParser.Float):
result = [ "float", { "size": 32 if cppType.type == "float" else 64 if cppType.type == "double" else 128 } ]
result = [ "number", { "float": True, "size": 32 if cppType.type == "float" else 64 if cppType.type == "double" else 128 } ]
# Null
elif isinstance(cppType, CppParser.Void):
result = [ "null", {} ]
Expand Down
55 changes: 30 additions & 25 deletions JsonGenerator/source/json_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,26 +252,25 @@ def cpp_native_type(self):
return "bool"


class JsonNumber(JsonNative, JsonType):
class JsonInteger(JsonNative, JsonType):
def __init__(self, name, parent, schema, size = config.DEFAULT_INT_SIZE, signed = False):
JsonType.__init__(self, name, parent, schema)
self.size = schema["size"] if "size" in schema else size

if self.size != 8 and self.size != 16 and self.size != 32 and self.size != 64:
raise JsonParseError("Invalid integer number size: '%s'" % self.print_name)

self.signed = schema["signed"] if "signed" in schema else signed
self._cpp_class = CoreJson("Dec%sInt%i" % ("S" if self.signed else "U", self.size))
self._cpp_native_type = "%sint%i_t" % ("" if self.signed else "u", self.size)
self.__cpp_class = CoreJson("Dec%sInt%i" % ("S" if self.signed else "U", self.size))
self.__cpp_native_type = "%sint%i_t" % ("" if self.signed else "u", self.size)

@property
def cpp_class(self):
return self._cpp_class
return self.__cpp_class

@property
def cpp_native_type(self):
return self._cpp_native_type


class JsonInteger(JsonNumber):
# Identical as Number
pass
return self.__cpp_native_type


class AuxJsonInteger(JsonInteger):
Expand All @@ -288,24 +287,27 @@ def cpp_native_type(self):
return "auto"


class JsonFloat(JsonNative, JsonType):
@property
def cpp_class(self):
return CoreJson("Float")
class JsonNumber(JsonNative, JsonType):
def __init__(self, name, parent, schema):
JsonType.__init__(self, name, parent, schema)
self.size = schema["size"] if "size" in schema else 32

@property
def cpp_native_type(self):
return "float"
if self.size > 64:
raise JsonParseError("Floating point numbers over 64 bits are not supported: '%s'" % self.print_name)

if self.size != 32 and self.size != 64:
raise JsonParseError("Invalid floating point number size: '%s'" % self.print_name)

self.__cpp_class = CoreJson("Float") if self.size == 32 else CoreJson("Double")
self.__cpp_native_type = "float" if self.size == 32 else "double"

class JsonDouble(JsonNative, JsonType):
@property
def cpp_class(self):
return CoreJson("Double")
return self.__cpp_class

@property
def cpp_native_type(self):
return "double"
return self.__cpp_native_type


class JsonString(JsonNative, JsonType):
Expand Down Expand Up @@ -876,12 +878,15 @@ def JsonItem(name, parent, schema, included=None):
elif schema["type"] == "integer":
return JsonInteger(name, parent, schema)
elif schema["type"] == "number":
return JsonNumber(name, parent, schema)
elif schema["type"] == "float":
return JsonFloat(name, parent, schema)
elif schema["type"] == "double":
return JsonDouble(name, parent, schema)
if ("float" in schema and schema["float"]) or ("example" in schema and '.' in str(schema["example"])):
return JsonNumber(name, parent, schema)
else:
log.Info("'%s': type is 'number' but assuming integer value" % name)
return JsonInteger(name, parent, schema)
else:
if schema["type"] == "float":
log.Print("For floating point type use '\"type\": \"number\"' with '\"float\": True' or with \"example\" using a decimal point")

raise JsonParseError("unsupported JSON type: '%s'" % schema["type"])
else:
raise JsonParseError("missing 'type' for item: '%s'" % name)
Expand Down
4 changes: 2 additions & 2 deletions ProxyStubGenerator/CppParser.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,10 +345,10 @@ def __init__(self, parent_block, parent, string, valid_specifiers, tags_allowed=
for s in "".join(string[i + 1]).split(".."):
try:
if '.' not in s:
v = eval(s.lower().replace("k","*1024").replace("m","*1024*1024").replace("g","*1024*1024*1024"))
v = int(eval(s.lower().replace("k","*1024").replace("m","*1024*1024").replace("g","*1024*1024*1024")))
else:
v = eval(s)
self.meta.range.append(int(v))
self.meta.range.append(v)
except:
raise ParserError("failed to evaluate range in @restrict: '%s'" % s)
if len(self.meta.range) == 2:
Expand Down
4 changes: 2 additions & 2 deletions ProxyStubGenerator/Log.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def __init__(self, name, verbose = False, warnings = True, doc_issues = False):
self.name = name
self.file = ""
if os.name == "posix":
self.info = "\033[0mINFO"
self.cinfo = "\033[36mINFO"
self.cwarn = "\033[33mWARNING"
self.cerror = "\033[31mERROR"
self.cdocissue = "\033[37mDOCUMENTATION"
Expand All @@ -30,7 +30,7 @@ def __Print(self, text, file=""):
def Info(self, text, file=""):
if self.show_infos:
if not file: file = self.file
self.infos.append("%s: %s: %s%s%s" % (self.name, self.info, file, ": " if file else "", text))
self.infos.append("%s: %s%s: %s%s%s" % (self.name, self.cinfo, self.creset, file, ": " if file else "", text))
self.__Print(self.infos[-1])

def DocIssue(self, text, file=""):
Expand Down
41 changes: 37 additions & 4 deletions ProxyStubGenerator/StubGenerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,8 +325,10 @@ def Convert(paramtype, retval, vars, hresult=False):

if param.IsPointer():
parsed = ParseLength(param, meta.length if meta.length else meta.maxlength, vars)

if parsed[1]:
length_param = parsed[1]

value = "BUFFER" + parsed[0]
else:
if paramtype.type.TypeName().endswith(HRESULT):
Expand All @@ -342,6 +344,7 @@ def Convert(paramtype, retval, vars, hresult=False):
value = "INT32"
elif p.size == "long long":
value = "INT64"

if not p.signed:
value = "U" + value

Expand All @@ -358,6 +361,7 @@ def Convert(paramtype, retval, vars, hresult=False):
break

rvalue = ["type = Type." + value]

if length_param:
rvalue.append("length_param = \"%s\"" % length_param)

Expand All @@ -369,18 +373,28 @@ def Convert(paramtype, retval, vars, hresult=False):
elif isinstance(p, CppParser.Bool):
return ["type = Type.BOOL"]

elif isinstance(p, CppParser.Float):
print(p)
if p.type == "float":
return ["type = Type.FLOAT32"]
elif p.type == "double":
return ["type = Type.FLOAT64"]

elif isinstance(p, CppParser.Class):
if param.IsPointer():
return ["type = Type.OBJECT", "class = \"%s\"" % Flatten(param.TypeName())]
else:
value = ["type = Type.POD", "class = \"%s\"" % Flatten(param.type.full_name)]
pod_params = []

for v in p.vars:
param_info = Convert(v, None, p.vars)
text = []
text.append("name = " + v.name)

if param_info:
text.extend(param_info)

pod_params.append("{ %s }" % ", ".join(text))

if pod_params:
Expand All @@ -391,14 +405,17 @@ def Convert(paramtype, retval, vars, hresult=False):
elif isinstance(p, CppParser.Enum):
value = "32"
signed = "U"

if p.type.Type().size == "char":
value = "8"
elif p.type.Type().size == "short":
value = "16"

if p.type.Type().signed:
signed = ""

name = Flatten(param.type.full_name)

if name not in enums_list:
data = dict()
for e in p.items:
Expand Down Expand Up @@ -598,7 +615,7 @@ def as_rvalue(self):

@property
def storage_size(self):
if isinstance(self.kind, (CppParser.Integer, CppParser.Enum, CppParser.BuiltinInteger)):
if isinstance(self.kind, (CppParser.Integer, CppParser.Float, CppParser.Enum, CppParser.BuiltinInteger)):
return "sizeof(%s)" % self.type_name
else:
Unreachable()
Expand Down Expand Up @@ -927,6 +944,9 @@ def _FindLength(length_name, variable_name):
if ((self.restrict_range[1] >= (64*1024)) and (self.restrict_range[1] < (16*1024*1024))):
self.type_name = "Core::Frame::UInt24"

if isinstance(self.kind, CppParser.Fundamental) and self.type.IsReference() and self.is_input_only:
log.WarnLine(self.identifier, "%s: input-only fundamental type passed by reference" % self.trace_proto)

@property
def as_rvalue(self):
def maybe_cast(expr):
Expand Down Expand Up @@ -985,8 +1005,14 @@ def read_rpc_type(self):
elif isinstance(self.kind, CppParser.Enum):
return "Number<%s>()" % self.type_name

# Floating point types
elif isinstance(self.kind, CppParser.Float):
if "long" not in self.type_name:
return "Number<%s>()" % self.type_name
else:
raise TypenameError(self.identifier, "long double type is not supported (see '%s')" % (self.trace_proto))
else:
raise TypenameError(self.identifier, "%s: unable to deserialise this type" % self.trace_proto)
raise TypenameError(self.identifier, "%s: unable to deserialise this type (see '%s')" % (self.type_name, self.trace_proto))

@property
def write_rpc_type(self):
Expand All @@ -1013,8 +1039,15 @@ def write_rpc_type(self):
elif isinstance(self.kind, CppParser.BuiltinInteger):
return "Number<%s>(%s)" % (self.type_name, self.as_rvalue)

# Floating point types
elif isinstance(self.kind, CppParser.Float):
if "long" not in self.type_name:
return "Number<%s>(%s)" % (self.type_name, self.as_rvalue)
else:
raise TypenameError(self.identifier, "long double is not supported (see '%s')" % (self.trace_proto))

else:
raise TypenameError(self.identifier, "%s: sorry, unable to serialise this type" % self.trace_proto)
raise TypenameError(self.identifier, "%s: sorry, unable to serialise this type (see '%s')" % (self.type_name, self.trace_proto))

@property
def storage_size(self):
Expand All @@ -1027,7 +1060,7 @@ def storage_size(self):
return "(sizeof(uint32_t))"
else:
return "Core::Frame::RealSize<%s>()" % self.peek_length.type_name
elif isinstance(self.kind, (CppParser.Integer, CppParser.Enum, CppParser.BuiltinInteger)):
elif isinstance(self.kind, (CppParser.Integer, CppParser.Float, CppParser.Enum, CppParser.BuiltinInteger)):
return "Core::Frame::RealSize<%s>()" % self.type_name
elif isinstance(self.kind, CppParser.Bool):
return 1 # always one byte
Expand Down

0 comments on commit 676594d

Please sign in to comment.