Project

General

Profile

Bug #459 ยป 0002-generate_packets.py-correctly-handle-JSON-sub-locati.patch

main - Alina Lenk, 04/16/2024 01:04 AM

View differences:

common/generate_packets.py
depth: int
"""The array nesting depth of this location; used to determine index
variable names."""
json_depth: int
"""The total sub-location nesting depth of the JSON field address
for this location"""
def __init__(self, name: str, location: "str | None" = None, depth: int = 0):
def __init__(self, name: str, location: "str | None" = None,
depth: int = 0, json_depth: "int | None" = None):
self.name = name
if location is None:
self.location = name
else:
self.location = location
self.location = location if location is not None else name
self.depth = depth
self.json_depth = json_depth if json_depth is not None else depth
def deeper(self, new_location: str) -> "Location":
def deeper(self, new_location: str, json_step: int = 1) -> "Location":
"""Return the given string as a new Location with the same name as
self and incremented depth"""
return type(self)(self.name, new_location, self.depth + 1)
return type(self)(self.name, new_location,
self.depth + 1, self.json_depth + json_step)
def sub_full(self, json_step: int = 1) -> "Location":
"""Like self.sub, but with the option to step the JSON nesting
depth by a different amount."""
return self.deeper(f"{self}[{self.index}]", json_step)
@property
def index(self) -> str:
......
added to the end.
`field` ~> `field[i]` ~> `field[i][j]` etc."""
return self.deeper(f"{self}[{self.index}]")
return self.sub_full()
@property
def json_subloc(self) -> str:
"""The plocation (JSON field address) to the sub-location
of this location's corresponding field address"""
return "field_addr.sub_location" + self.json_depth * "->sub_location"
def __str__(self) -> str:
return self.location
......
}}
"""
def _get_code_put_full(self, location: Location, inner_put: str) -> str:
def _get_code_put_full(self, location: Location) -> str:
"""Helper method. Generate put code without array-diff."""
inner_put = prefix(" ", inner_put)
inner_put = prefix(" ", self.elem.get_code_put(location.sub, False))
return f"""\
{{
int {location.index};
......
e |= DIO_PUT(farray, &dout, &field_addr, {self.size.real});
/* Enter the array. */
field_addr.sub_location = plocation_elem_new(0);
{location.json_subloc} = plocation_elem_new(0);
#endif /* FREECIV_JSON_CONNECTION */
for ({location.index} = 0; {location.index} < {self.size.real}; {location.index}++) {{
#ifdef FREECIV_JSON_CONNECTION
/* Next array element. */
field_addr.sub_location->number = {location.index};
{location.json_subloc}->number = {location.index};
#endif /* FREECIV_JSON_CONNECTION */
{inner_put}\
}}
#ifdef FREECIV_JSON_CONNECTION
/* Exit array. */
FC_FREE(field_addr.sub_location);
FC_FREE({location.json_subloc});
#endif /* FREECIV_JSON_CONNECTION */
}}
"""
def _get_code_put_diff(self, location: Location, inner_put: str) -> str:
def _get_code_put_diff(self, location: Location) -> str:
"""Helper method. Generate array-diff put code."""
inner_put = prefix(" ", inner_put)
inner_cmp = prefix(" ", self.elem.get_code_cmp(location.sub))
# we're nesting two levels deep in the JSON structure
sub = location.sub_full(2)
inner_put = prefix(" ", self.elem.get_code_put(sub, True))
inner_cmp = prefix(" ", self.elem.get_code_cmp(sub))
return f"""\
{{
int {location.index};
......
e |= DIO_PUT(farray, &dout, &field_addr, 0);
/* Enter array. */
field_addr.sub_location = plocation_elem_new(0);
{location.json_subloc} = plocation_elem_new(0);
#endif /* FREECIV_JSON_CONNECTION */
fc_assert({self.size.real} < MAX_UINT16);
......
if (differ) {{
#ifdef FREECIV_JSON_CONNECTION
/* Append next diff array element. */
field_addr.sub_location->number = -1;
{location.json_subloc}->number = -1;
/* Create the diff array element. */
e |= DIO_PUT(farray, &dout, &field_addr, 2);
/* Enter diff array element (start at the index address). */
field_addr.sub_location->number = count_{location.index}++;
field_addr.sub_location->sub_location = plocation_elem_new(0);
{location.json_subloc}->number = count_{location.index}++;
{location.json_subloc}->sub_location = plocation_elem_new(0);
#endif /* FREECIV_JSON_CONNECTION */
e |= DIO_PUT(uint16, &dout, &field_addr, {location.index});
#ifdef FREECIV_JSON_CONNECTION
/* Content address. */
field_addr.sub_location->sub_location->number = 1;
{location.json_subloc}->sub_location->number = 1;
#endif /* FREECIV_JSON_CONNECTION */
{inner_put}\
#ifdef FREECIV_JSON_CONNECTION
/* Exit diff array element. */
FC_FREE(field_addr.sub_location->sub_location);
FC_FREE({location.json_subloc}->sub_location);
#endif /* FREECIV_JSON_CONNECTION */
}}
}}
#ifdef FREECIV_JSON_CONNECTION
/* Append diff array element. */
field_addr.sub_location->number = -1;
{location.json_subloc}->number = -1;
/* Create the terminating diff array element. */
e |= DIO_PUT(farray, &dout, &field_addr, 1);
/* Enter diff array element (start at the index address). */
field_addr.sub_location->number = count_{location.index};
field_addr.sub_location->sub_location = plocation_elem_new(0);
{location.json_subloc}->number = count_{location.index};
{location.json_subloc}->sub_location = plocation_elem_new(0);
#endif /* FREECIV_JSON_CONNECTION */
e |= DIO_PUT(uint16, &dout, &field_addr, MAX_UINT16);
#ifdef FREECIV_JSON_CONNECTION
/* Exit diff array element. */
FC_FREE(field_addr.sub_location->sub_location);
FC_FREE({location.json_subloc}->sub_location);
/* Exit array. */
FC_FREE(field_addr.sub_location);
FC_FREE({location.json_subloc});
#endif /* FREECIV_JSON_CONNECTION */
}}
"""
def get_code_put(self, location: Location, deep_diff: bool = False) -> str:
inner_put = self.elem.get_code_put(location.sub, deep_diff)
if deep_diff:
return self._get_code_put_diff(location, inner_put)
return self._get_code_put_diff(location)
else:
return self._get_code_put_full(location, inner_put)
return self._get_code_put_full(location)
def _get_code_get_full(self, location: Location, inner_get: str) -> str:
def _get_code_get_full(self, location: Location) -> str:
"""Helper method. Generate get code without array-diff."""
size_check = prefix(" ", self.size.receive_size_check(location.name))
inner_get = prefix(" ", inner_get)
inner_get = prefix(" ", self.elem.get_code_get(location.sub, False))
return f"""\
{{
int {location.index};
#ifdef FREECIV_JSON_CONNECTION
/* Enter array. */
field_addr.sub_location = plocation_elem_new(0);
{location.json_subloc} = plocation_elem_new(0);
#endif /* FREECIV_JSON_CONNECTION */
{size_check}\
for ({location.index} = 0; {location.index} < {self.size.real}; {location.index}++) {{
#ifdef FREECIV_JSON_CONNECTION
field_addr.sub_location->number = {location.index};
{location.json_subloc}->number = {location.index};
#endif /* FREECIV_JSON_CONNECTION */
{inner_get}\
}}
#ifdef FREECIV_JSON_CONNECTION
/* Exit array. */
FC_FREE(field_addr.sub_location);
FC_FREE({location.json_subloc});
#endif /* FREECIV_JSON_CONNECTION */
}}
"""
def _get_code_get_diff(self, location: Location, inner_get: str) -> str:
def _get_code_get_diff(self, location: Location) -> str:
"""Helper method. Generate array-diff get code."""
inner_get = prefix(" ", inner_get)
# we're nested two levels deep in the JSON structure
inner_get = prefix(" ", self.elem.get_code_get(location.sub_full(2), True))
return f"""\
{{
#ifdef FREECIV_JSON_CONNECTION
int count;
int count_{location.index};
/* Enter array. */
field_addr.sub_location = plocation_elem_new(0);
{location.json_subloc} = plocation_elem_new(0);
for (count = 0;; count++) {{
for (count_{location.index} = 0;; count_{location.index}++) {{
int {location.index};
field_addr.sub_location->number = count;
{location.json_subloc}->number = count_{location.index};
/* Enter diff array element (start at the index address). */
field_addr.sub_location->sub_location = plocation_elem_new(0);
{location.json_subloc}->sub_location = plocation_elem_new(0);
#else /* FREECIV_JSON_CONNECTION */
while (TRUE) {{
int {location.index};
......
if ({location.index} == MAX_UINT16) {{
#ifdef FREECIV_JSON_CONNECTION
/* Exit diff array element. */
FC_FREE(field_addr.sub_location->sub_location);
FC_FREE({location.json_subloc}->sub_location);
/* Exit diff array. */
FC_FREE(field_addr.sub_location);
FC_FREE({location.json_subloc});
#endif /* FREECIV_JSON_CONNECTION */
break;
......
}} else {{
#ifdef FREECIV_JSON_CONNECTION
/* Content address. */
field_addr.sub_location->sub_location->number = 1;
{location.json_subloc}->sub_location->number = 1;
#endif /* FREECIV_JSON_CONNECTION */
{inner_get}\
}}
#ifdef FREECIV_JSON_CONNECTION
/* Exit diff array element. */
FC_FREE(field_addr.sub_location->sub_location);
FC_FREE({location.json_subloc}->sub_location);
#endif /* FREECIV_JSON_CONNECTION */
}}
#ifdef FREECIV_JSON_CONNECTION
/* Exit array. */
FC_FREE(field_addr.sub_location);
FC_FREE({location.json_subloc});
#endif /* FREECIV_JSON_CONNECTION */
}}
"""
def get_code_get(self, location: Location, deep_diff: bool = False) -> str:
inner_get = self.elem.get_code_get(location.sub, deep_diff)
if deep_diff:
return self._get_code_get_diff(location, inner_get)
return self._get_code_get_diff(location)
else:
return self._get_code_get_full(location, inner_get)
return self._get_code_get_full(location)
def __str__(self) -> str:
return f"{self.elem}[{self.size}]"
    (1-1/1)