blob: 15fd095f49ee1ff7375f7a443f14cb45dd0fdf8a [file] [log] [blame]
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.build.config;
import java.io.PrintStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
public class MakeWriter {
public static final int FLAG_WRITE_HEADER = 1;
public static final int FLAG_WRITE_ANNOTATIONS = 1 << 1;
private final boolean mWriteHeader;
private final boolean mWriteAnnotations;
public static void write(PrintStream out, GenericConfig config, int flags) {
(new MakeWriter(flags)).writeGeneric(out, config);
}
public static void write(PrintStream out, FlatConfig config, int flags) {
(new MakeWriter(flags)).writeFlat(out, config);
}
private MakeWriter(int flags) {
mWriteHeader = (flags & FLAG_WRITE_HEADER) != 0;
mWriteAnnotations = (flags & FLAG_WRITE_ANNOTATIONS) != 0;
}
private void writeGeneric(PrintStream out, GenericConfig config) {
for (GenericConfig.ConfigFile file: config.getFiles().values()) {
out.println("---------------------------------------------------------");
out.println("FILE: " + file.getFilename());
out.println("---------------------------------------------------------");
writeFile(out, config, file);
out.println();
}
out.println("---------------------------------------------------------");
out.println("VARIABLES TOUCHED BY MAKE BASED CONFIG:");
out.println("---------------------------------------------------------");
writeStrVars(out, OutputChecker.getModifiedVars(config.getInitialVariables(),
config.getFinalVariables()), config);
}
private void writeFile(PrintStream out, GenericConfig config, GenericConfig.ConfigFile file) {
if (mWriteHeader) {
out.println("# This file is generated by the product_config tool");
}
for (GenericConfig.Statement statement: file.getStatements()) {
if (statement instanceof GenericConfig.Assign) {
writeAssign(out, config, (GenericConfig.Assign)statement);
} else if (statement instanceof GenericConfig.Inherit) {
writeInherit(out, (GenericConfig.Inherit)statement);
} else {
throw new RuntimeException("Unexpected Statement: " + statement);
}
}
}
private void writeAssign(PrintStream out, GenericConfig config,
GenericConfig.Assign statement) {
final List<Str> values = statement.getValue();
final int size = values.size();
final String varName = statement.getName();
Position pos = null;
if (size == 0) {
return;
} else if (size == 1) {
// Plain :=
final Str value = values.get(0);
out.print(varName + " := " + value);
pos = value.getPosition();
} else if (size == 2 && values.get(0).toString().length() == 0) {
// Plain +=
final Str value = values.get(1);
out.print(varName + " += " + value);
pos = value.getPosition();
} else {
// Write it out the long way
out.print(varName + " := " + values.get(0));
for (int i = 1; i < size; i++) {
out.print("$(" + varName + ") " + values.get(i));
pos = values.get(i).getPosition();
}
}
if (mWriteAnnotations) {
out.print(" # " + config.getVarType(varName) + " " + pos);
}
out.println();
}
private void writeInherit(PrintStream out, GenericConfig.Inherit statement) {
final Str filename = statement.getFilename();
out.print("$(call inherit-product " + filename + ")");
if (mWriteAnnotations) {
out.print(" # " + filename.getPosition());
}
out.println();
}
private static class Var {
Var(String name, Str val) {
this.name = name;
this.val = val;
}
final String name;
final Str val;
}
private static void writeStrVars(PrintStream out, Map<String, Str> vars, ConfigBase config) {
// Sort by file name and var name
TreeMap<String, Var> sorted = new TreeMap();
for (Map.Entry<String, Str> entry: vars.entrySet()) {
sorted.put(entry.getValue().getPosition().toString() + " " + entry.getKey(),
new Var(entry.getKey(), entry.getValue()));
}
// Print it
for (Var var: sorted.values()) {
out.println(var.val.getPosition() + var.name + " := " + var.val);
}
}
private void writeFlat(PrintStream out, FlatConfig config) {
// TODO: Print positions.
for (Map.Entry<String, Value> entry: config.getValues().entrySet()) {
out.print(entry.getKey());
out.print(" := ");
final Value value = entry.getValue();
if (value.getVarType() == VarType.LIST) {
final List<Str> list = value.getList();
final int size = list.size();
for (int i = 0; i < size; i++) {
out.print(list.get(i).toString());
if (i != size - 1) {
out.print(" \\\n ");
}
}
} else {
out.print(value.getStr().toString());
}
out.println();
}
}
}