Ejemplo n.º 1
0
    def parse_configuration_comamnd(self, res, parts):
        inst = Namespace(type='configuration')
        res.instructions.append(inst)

        if len(parts) == 2:
            inst.name = strip_quotes(parts[1])
        else:
            assert len(parts) == 1

        def generic_prop_group(group_data, body_parts):

            group = Namespace()
            inst.setdefault(group_data.pythonized, []).append(group)

            if group_data.nargs > 0:
                group.args = body_parts[1:group_data.nargs + 1]

            if len(body_parts) == group_data.nargs + 2:
                group.cond = parse_cond(body_parts[-1])
            else:
                assert len(body_parts) == group_data.nargs + 1

            if group_data.allow_body:
                for cmd, body_parts in self.parse_body_commands(
                        lowercase=False):
                    group.setdefault(cmd, []).append(body_parts[1:])
            elif self.token.type == '{':
                # TODO(maximsmol): use the real name here
                self.die(
                    f'Configuration command {group_data.pythonized} should not have a body.'
                )

        for cmd, body_parts in self.parse_body_commands(lowercase=False):
            if cmd not in configuration_commands:
                self.die(f'Unknown configuration command {cf.bold(cmd)}.')

            generic_prop_group(configuration_commands[cmd], body_parts)
Ejemplo n.º 2
0
    def parse_command(self, res):
        parts = self.parse_command_parts()
        cmd = self.need_command(parts, lowercase=False)
        if cmd == 'Macro':
            name = string_like(parts[1])
            # TODO(maximsmol): weird unquoted macro values are allowed
            #                  and we skip the spaces in them + this parsing
            #                  is all around weird
            value = string_like(parts[2])

            cond = None
            if len(parts) > 3:
                # TODO(maximsmol): check that weird unquoted macros are unquoted
                value_parts = [value]
                i = 3
                for p in parts[3:]:
                    if p.type == 'cond':
                        cond = parse_cond(parts[3])
                        assert i == len(parts) - 1
                        break

                    value_parts.append(raw_string(p))
                    i += 1
                # TODO(maximsmol): this actually loses some whitespaces
                value = ' '.join(value_parts)
            else:
                assert len(parts) == 3

            inst = Namespace(type='macro')
            inst.name = name
            inst.value = value
            if cond is not None:
                inst.cond = cond
            res.instructions.append(inst)
        elif cmd == 'Conditional':
            name = raw_string(parts[1])

            inst = Namespace(type='conditional')
            res.instructions.append(inst)

            inst.name = name
            inst.value = strip_quotes(parts[2])

            cond = None
            if len(parts) == 4:
                inst.cond = parse_cond(parts[3])
            else:
                assert len(parts) == 3
        elif cmd == 'MacroRequired':
            inst = Namespace(type='macro_required')

            if len(parts) == 3:
                inst.default = strip_quotes(parts[2])
            else:
                assert len(parts) == 2

            inst.name = string_like(parts[1])
            inst.allow_empty = False
        elif cmd == 'MacroRequiredAllowEmpty':
            inst = Namespace(type='macro_required')

            if len(parts) == 3:
                inst.default = strip_quotes(parts[2])
            else:
                assert len(parts) == 2

            inst.name = string_like(parts[1])
            inst.allow_empty = True
        elif cmd == 'LoadAddressMacro':
            inst = Namespace(type='address_macro')
            res.instructions.append(inst)

            assert len(parts) == 2

            inst.name = raw_string(parts[1])

            for body_parts in self.parse_body():
                # TODO(maximsmol): parse this
                # this is only used on XBOX afaik
                pass
        elif cmd == 'LoadAddressMacroAuto':
            inst = Namespace(type='address_macro_auto')
            res.instructions.append(inst)

            assert len(parts) == 4

            inst.name = raw_string(parts[1])

            inst.addr = int(raw_string(parts[2]), 16)
            inst.cond = parse_cond(parts[3])

            for body_parts in self.parse_body():
                # TODO(maximsmol): parse this
                # this is only used on XBOX afaik
                pass
        elif cmd == 'IgnoreRedundancyWarning':
            inst = Namespace(type='ignore_redundancy_warning')
            assert len(parts) == 2

            inst.value = strip_quotes(parts[1]).lower()
        elif cmd in ['Include',
                     'include']:  # Valve, why do you insist on mixing case
            path = strip_quotes(parts[1])
            cond = None
            if len(parts) == 3:
                cond = parse_cond(parts[2])
            else:
                assert len(parts) == 2

            inst = Namespace(type='include')
            inst.path = path
            if cond is not None:
                inst.cond = cond
            res.instructions.append(inst)
        elif cmd == 'Configuration':
            self.parse_configuration_comamnd(res, parts)
        elif cmd == 'Project':
            proj = Namespace(type='project', folders=Namespace(), files=[])
            res.instructions.append(proj)

            if len(parts) == 2:
                name = strip_quotes(parts[1])
            else:
                assert len(parts) == 1

            for cmd, body_parts in self.parse_body_commands():
                if cmd == 'folder':
                    self.parse_folder_command(proj, body_parts)
                elif cmd in ['file']:
                    self.parse_file_command(proj.files, parts)
                else:
                    self.die(f'Unknown project command {cf.bold(cmd)}.')
        elif cmd == 'CustomBuildStep':
            self.parse_cmd_list_schema(res, project_schema, parts)
            # TODO(maximsmol): type will be renamed to name
            res.instructions[-1].type = cmd
        else:
            self.die(f'Unknown command {cf.bold(cmd)}.')