Exemple #1
0
    def _generate_era_item(self, era: ZoneEraRaw) -> str:
        policy_name = era['rules']
        if policy_name in ['-', ':']:
            zone_policy = f"'{policy_name}'"
        else:
            zone_policy = f'ZONE_POLICY_{normalize_name(policy_name)}'

        return self.ZONE_ERA_ITEM.format(
            raw_line=normalize_raw(era['raw_line']),
            offset_seconds=era['offset_seconds_truncated'],
            zone_policy=zone_policy,
            rules_delta_seconds=era['rules_delta_seconds_truncated'],
            format=era['format'],  # preserve the %s
            until_year=era['until_year'],
            until_month=era['until_month'],
            until_day=era['until_day'],
            until_seconds=era['until_seconds_truncated'],
            until_time_suffix=era['until_time_suffix'])
Exemple #2
0
 def _generate_policy_item(self, name: str,
                           rules: List[ZoneRuleRaw]) -> str:
     rule_items = ''
     for rule in rules:
         rule_items += self.ZONE_RULE_ITEM.format(
             policyName=normalize_name(name),
             raw_line=normalize_raw(rule['raw_line']),
             from_year=rule['from_year'],
             to_year=rule['to_year'],
             in_month=rule['in_month'],
             on_day_of_week=rule['on_day_of_week'],
             on_day_of_month=rule['on_day_of_month'],
             at_seconds=rule['at_seconds_truncated'],
             at_time_suffix=rule['at_time_suffix'],
             delta_seconds=rule['delta_seconds_truncated'],
             letter=rule['letter'])
     return self.ZONE_POLICY_ITEM.format(policyName=normalize_name(name),
                                         numRules=len(rules),
                                         ruleItems=rule_items)
Exemple #3
0
    def _generate_era_item(self, zone_name: str,
                           era: ZoneEraRaw) -> Tuple[str, int]:
        rules_policy_name = era['rules']
        if rules_policy_name == '-' or rules_policy_name == ':':
            zone_policy = 'nullptr'
        else:
            zone_policy = f'&kPolicy{normalize_name(rules_policy_name)}'

        offset_code = era['offset_code']
        delta_code = era['delta_code_encoded']
        delta_code_comment = _get_era_delta_code_comment(
            offset_seconds=era['offset_seconds_truncated'],
            delta_seconds=era['rules_delta_seconds_truncated'],
            scope=self.scope,
        )
        until_year_tiny = era['until_year_tiny']
        until_month = era['until_month']
        until_day = era['until_day']
        until_time_code = era['until_time_code']
        until_time_modifier = era['until_time_modifier']
        until_time_modifier_comment = _get_time_modifier_comment(
            time_seconds=era['until_seconds_truncated'],
            suffix=era['until_time_suffix'],
        )
        format_short = era['format_short']
        string_length = len(format_short) + 1

        era_item = self.ZONE_INFOS_CPP_ERA_ITEM.format(
            raw_line=normalize_raw(era['raw_line']),
            offset_code=offset_code,
            delta_code=delta_code,
            delta_code_comment=delta_code_comment,
            zone_policy=zone_policy,
            format=format_short,
            until_year_tiny=until_year_tiny,
            until_month=until_month,
            until_day=until_day,
            until_time_code=until_time_code,
            until_time_modifier=until_time_modifier,
            until_time_modifier_comment=until_time_modifier_comment,
        )

        return (era_item, string_length)
Exemple #4
0
    def _generate_policy_item(
        self,
        name: str,
        rules: List[ZoneRuleRaw],
        indexed_letters: Optional[IndexMap],
    ) -> Tuple[str, int, int]:
        ZONE_POLICIES_CPP_RULE_ITEM = """\
  // {raw_line}
  {{
    {from_year_tiny} /*fromYearTiny*/,
    {to_year_tiny} /*toYearTiny*/,
    {in_month} /*inMonth*/,
    {on_day_of_week} /*onDayOfWeek*/,
    {on_day_of_month} /*onDayOfMonth*/,
    {at_time_code} /*atTimeCode*/,
    {at_time_modifier} /*atTimeModifier ({at_time_modifier_comment})*/,
    {delta_code} /*deltaCode ({delta_code_comment})*/,
    {letter} /*letter{letterComment}*/,
  }},
"""
        ZONE_POLICIES_LETTER_ARRAY = """\
static const char* const kLetters{policyName}[] {progmem} = {{
{letterItems}
}};
"""

        # Generate kZoneRules*[]
        rule_items = ''
        for rule in rules:
            at_time_code = rule['at_time_code']
            at_time_modifier = rule['at_time_modifier']
            at_time_modifier_comment = _get_time_modifier_comment(
                time_seconds=rule['at_seconds_truncated'],
                suffix=rule['at_time_suffix'],
            )
            delta_code = rule['delta_code_encoded']
            delta_code_comment = _get_rule_delta_code_comment(
                delta_seconds=rule['delta_seconds_truncated'],
                scope=self.scope,
            )
            from_year_tiny = rule['from_year_tiny']
            to_year_tiny = rule['to_year_tiny']

            # Single-character 'letter' values are represented as themselves
            # using the C++ 'char' type ('A'-'Z'). But some 'letter' fields hold
            # a multi-character string. We can encode these multi-character
            # strings as an index into an array of NUL-terminated strings.
            # ASCII codes less than 32 (space) are non-printable control
            # characters so they will not collide with the printable characters
            # 'A' - 'Z'. Therefore we can hold to up to 31 multi-character
            # strings per-zone. In practice, for a single zone, the maximum
            # number of multi-character strings that I've seen is 2.
            letter = rule['letter']
            if len(letter) == 1:
                letterComment = ''
                letter = f"'{letter}'"
            elif len(letter) > 1:
                letterComment = f' (index to "{letter}")'
                letter = str(rule['letter_index_per_policy'])
            else:
                raise Exception('len(%s) == 0; should not happen' %
                                rule['letter'])

            rule_items += ZONE_POLICIES_CPP_RULE_ITEM.format(
                raw_line=normalize_raw(rule['raw_line']),
                from_year_tiny=from_year_tiny,
                to_year_tiny=to_year_tiny,
                in_month=rule['in_month'],
                on_day_of_week=rule['on_day_of_week'],
                on_day_of_month=rule['on_day_of_month'],
                at_time_code=at_time_code,
                at_time_modifier=at_time_modifier,
                at_time_modifier_comment=at_time_modifier_comment,
                delta_code=delta_code,
                delta_code_comment=delta_code_comment,
                letter=letter,
                letterComment=letterComment)

        # Generate kLetters*[]
        policy_name = normalize_name(name)
        num_letters = len(indexed_letters) if indexed_letters else 0
        memory_letters8 = 0
        memory_letters32 = 0
        if num_letters:
            assert indexed_letters is not None
            letter_array_ref = f'kLetters{policy_name}'
            letterItems = ''
            for name, index in indexed_letters.items():
                letterItems += f'  /*{index}*/ "{name}",\n'
                memory_letters8 += len(name) + 1 + 2  # NUL terminated
                memory_letters32 += len(name) + 1 + 4  # NUL terminated
            letter_array = ZONE_POLICIES_LETTER_ARRAY.format(
                policyName=policy_name,
                letterItems=letterItems,
                progmem='ACE_TIME_PROGMEM')
        else:
            letter_array_ref = 'nullptr'
            letter_array = ''

        # Calculate the memory consumed by structs and arrays
        num_rules = len(rules)
        memory8 = (1 * self.SIZEOF_ZONE_POLICY_8 +
                   num_rules * self.SIZEOF_ZONE_RULE_8 + memory_letters8)
        memory32 = (1 * self.SIZEOF_ZONE_POLICY_32 +
                    num_rules * self.SIZEOF_ZONE_RULE_32 + memory_letters32)

        policy_item = self.ZONE_POLICIES_CPP_POLICY_ITEM.format(
            scope=self.scope,
            policyName=policy_name,
            numRules=num_rules,
            memory8=memory8,
            memory32=memory32,
            ruleItems=rule_items,
            numLetters=num_letters,
            letterArrayRef=letter_array_ref,
            letterArray=letter_array,
            progmem='ACE_TIME_PROGMEM')

        return (policy_item, memory8, memory32)