11aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber/* 21aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * Copyright (C) 2016 The Android Open Source Project 31aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * 41aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 51aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * you may not use this file except in compliance with the License. 61aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * You may obtain a copy of the License at 71aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * 81aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 91aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * 101aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * Unless required by applicable law or agreed to in writing, software 111aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 121aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * See the License for the specific language governing permissions and 141aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * limitations under the License. 151aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber */ 161aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber 17c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber#include "Formatter.h" 18c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber 19c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber#include <assert.h> 20c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber 21c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Hubernamespace android { 22c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber 23881227d860c59471eee31d39946e96ce2daa35d6Andreas HuberFormatter::Formatter(FILE *file) 24881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber : mFile(file == NULL ? stdout : file), 25881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber mIndentDepth(0), 26c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber mAtStartOfLine(true) { 27c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber} 28c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber 29881227d860c59471eee31d39946e96ce2daa35d6Andreas HuberFormatter::~Formatter() { 30881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber if (mFile != stdout) { 31881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber fclose(mFile); 32881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber } 33881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber mFile = NULL; 34881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber} 35881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber 360a68a28cde91706a64b0465b24c7171f9f4cde99Yifan Hongvoid Formatter::indent(size_t level) { 370a68a28cde91706a64b0465b24c7171f9f4cde99Yifan Hong mIndentDepth += level; 38c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber} 39c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber 400a68a28cde91706a64b0465b24c7171f9f4cde99Yifan Hongvoid Formatter::unindent(size_t level) { 410a68a28cde91706a64b0465b24c7171f9f4cde99Yifan Hong assert(mIndentDepth >= level); 420a68a28cde91706a64b0465b24c7171f9f4cde99Yifan Hong mIndentDepth -= level; 430a68a28cde91706a64b0465b24c7171f9f4cde99Yifan Hong} 440a68a28cde91706a64b0465b24c7171f9f4cde99Yifan Hong 45a018ed53b332ed0d184ae4c53e89a2036f117b58Yifan HongFormatter &Formatter::indent(size_t level, std::function<void(void)> func) { 460a68a28cde91706a64b0465b24c7171f9f4cde99Yifan Hong this->indent(level); 470a68a28cde91706a64b0465b24c7171f9f4cde99Yifan Hong func(); 480a68a28cde91706a64b0465b24c7171f9f4cde99Yifan Hong this->unindent(level); 49a018ed53b332ed0d184ae4c53e89a2036f117b58Yifan Hong return *this; 50a018ed53b332ed0d184ae4c53e89a2036f117b58Yifan Hong} 51a018ed53b332ed0d184ae4c53e89a2036f117b58Yifan Hong 52a018ed53b332ed0d184ae4c53e89a2036f117b58Yifan HongFormatter &Formatter::indent(std::function<void(void)> func) { 53a018ed53b332ed0d184ae4c53e89a2036f117b58Yifan Hong return this->indent(1, func); 540a68a28cde91706a64b0465b24c7171f9f4cde99Yifan Hong} 550a68a28cde91706a64b0465b24c7171f9f4cde99Yifan Hong 56a018ed53b332ed0d184ae4c53e89a2036f117b58Yifan HongFormatter &Formatter::block(std::function<void(void)> func) { 57a018ed53b332ed0d184ae4c53e89a2036f117b58Yifan Hong (*this) << "{\n"; 58a018ed53b332ed0d184ae4c53e89a2036f117b58Yifan Hong this->indent(func); 59a018ed53b332ed0d184ae4c53e89a2036f117b58Yifan Hong return (*this) << "}"; 60c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber} 61c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber 622009699f1106709cf4bfb281e78efb4f3d04f1c6Yifan Hongvoid Formatter::setLinePrefix(const std::string &prefix) { 632009699f1106709cf4bfb281e78efb4f3d04f1c6Yifan Hong mLinePrefix = prefix; 642009699f1106709cf4bfb281e78efb4f3d04f1c6Yifan Hong} 652009699f1106709cf4bfb281e78efb4f3d04f1c6Yifan Hong 662009699f1106709cf4bfb281e78efb4f3d04f1c6Yifan Hongvoid Formatter::unsetLinePrefix() { 672009699f1106709cf4bfb281e78efb4f3d04f1c6Yifan Hong mLinePrefix = ""; 682009699f1106709cf4bfb281e78efb4f3d04f1c6Yifan Hong} 692009699f1106709cf4bfb281e78efb4f3d04f1c6Yifan Hong 70a018ed53b332ed0d184ae4c53e89a2036f117b58Yifan HongFormatter &Formatter::endl() { 71a018ed53b332ed0d184ae4c53e89a2036f117b58Yifan Hong return (*this) << "\n"; 72a018ed53b332ed0d184ae4c53e89a2036f117b58Yifan Hong} 73a018ed53b332ed0d184ae4c53e89a2036f117b58Yifan Hong 74a018ed53b332ed0d184ae4c53e89a2036f117b58Yifan HongFormatter &Formatter::sIf(const std::string &cond, std::function<void(void)> block) { 75a018ed53b332ed0d184ae4c53e89a2036f117b58Yifan Hong (*this) << "if (" << cond << ") "; 76a018ed53b332ed0d184ae4c53e89a2036f117b58Yifan Hong return this->block(block); 77a018ed53b332ed0d184ae4c53e89a2036f117b58Yifan Hong} 78a018ed53b332ed0d184ae4c53e89a2036f117b58Yifan Hong 79a018ed53b332ed0d184ae4c53e89a2036f117b58Yifan HongFormatter &Formatter::sElseIf(const std::string &cond, std::function<void(void)> block) { 80a018ed53b332ed0d184ae4c53e89a2036f117b58Yifan Hong (*this) << " else if (" << cond << ") "; 81a018ed53b332ed0d184ae4c53e89a2036f117b58Yifan Hong return this->block(block); 82a018ed53b332ed0d184ae4c53e89a2036f117b58Yifan Hong} 83a018ed53b332ed0d184ae4c53e89a2036f117b58Yifan Hong 84a018ed53b332ed0d184ae4c53e89a2036f117b58Yifan HongFormatter &Formatter::sElse(std::function<void(void)> block) { 85a018ed53b332ed0d184ae4c53e89a2036f117b58Yifan Hong (*this) << " else "; 86a018ed53b332ed0d184ae4c53e89a2036f117b58Yifan Hong return this->block(block); 87a018ed53b332ed0d184ae4c53e89a2036f117b58Yifan Hong} 88a018ed53b332ed0d184ae4c53e89a2036f117b58Yifan Hong 8931f07ffea072ad066bc73181f3368951ba21f50dYifan HongFormatter &Formatter::sFor(const std::string &stmts, std::function<void(void)> block) { 9031f07ffea072ad066bc73181f3368951ba21f50dYifan Hong (*this) << "for (" << stmts << ") "; 9131f07ffea072ad066bc73181f3368951ba21f50dYifan Hong return this->block(block); 9231f07ffea072ad066bc73181f3368951ba21f50dYifan Hong} 9331f07ffea072ad066bc73181f3368951ba21f50dYifan Hong 94e45b5303e072043679483a70606f6c00dde17382Yifan HongFormatter &Formatter::sTry(std::function<void(void)> block) { 95e45b5303e072043679483a70606f6c00dde17382Yifan Hong (*this) << "try "; 96e45b5303e072043679483a70606f6c00dde17382Yifan Hong return this->block(block); 97e45b5303e072043679483a70606f6c00dde17382Yifan Hong} 98e45b5303e072043679483a70606f6c00dde17382Yifan Hong 99e45b5303e072043679483a70606f6c00dde17382Yifan HongFormatter &Formatter::sCatch(const std::string &exception, std::function<void(void)> block) { 100e45b5303e072043679483a70606f6c00dde17382Yifan Hong (*this) << " catch (" << exception << ") "; 101e45b5303e072043679483a70606f6c00dde17382Yifan Hong return this->block(block); 102e45b5303e072043679483a70606f6c00dde17382Yifan Hong} 103e45b5303e072043679483a70606f6c00dde17382Yifan Hong 1044de083b1791414410fd9add633ccbb8e56b15036Martijn CoenenFormatter &Formatter::sFinally(std::function<void(void)> block) { 1054de083b1791414410fd9add633ccbb8e56b15036Martijn Coenen (*this) << " finally "; 1064de083b1791414410fd9add633ccbb8e56b15036Martijn Coenen return this->block(block); 1074de083b1791414410fd9add633ccbb8e56b15036Martijn Coenen} 1084de083b1791414410fd9add633ccbb8e56b15036Martijn Coenen 10931f07ffea072ad066bc73181f3368951ba21f50dYifan HongFormatter &Formatter::sWhile(const std::string &cond, std::function<void(void)> block) { 11031f07ffea072ad066bc73181f3368951ba21f50dYifan Hong (*this) << "while (" << cond << ") "; 11131f07ffea072ad066bc73181f3368951ba21f50dYifan Hong return this->block(block); 11231f07ffea072ad066bc73181f3368951ba21f50dYifan Hong} 11331f07ffea072ad066bc73181f3368951ba21f50dYifan Hong 1145158db484e5ab302368f191d75d5b1334c270e52Zhuoyao ZhangFormatter &Formatter::operator<<(const std::string &out) { 115c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber const size_t len = out.length(); 116c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber size_t start = 0; 117c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber while (start < len) { 118c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber size_t pos = out.find("\n", start); 119c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber 1205158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang if (pos == std::string::npos) { 121c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber if (mAtStartOfLine) { 1222009699f1106709cf4bfb281e78efb4f3d04f1c6Yifan Hong fprintf(mFile, "%s", mLinePrefix.c_str()); 123b06cc82425d035b14e4d86a50d5980b836f067fdYifan Hong fprintf(mFile, "%*s", (int)(4 * mIndentDepth), ""); 124c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber mAtStartOfLine = false; 125c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber } 126c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber 1270e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber output(out.substr(start)); 128c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber break; 129c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber } 130c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber 131c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber if (pos == start) { 132881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber fprintf(mFile, "\n"); 133c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber mAtStartOfLine = true; 134c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber } else if (pos > start) { 135c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber if (mAtStartOfLine) { 1362009699f1106709cf4bfb281e78efb4f3d04f1c6Yifan Hong fprintf(mFile, "%s", mLinePrefix.c_str()); 137b06cc82425d035b14e4d86a50d5980b836f067fdYifan Hong fprintf(mFile, "%*s", (int)(4 * mIndentDepth), ""); 138c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber } 139c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber 1400e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber output(out.substr(start, pos - start + 1)); 141c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber 142c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber mAtStartOfLine = true; 143c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber } 144c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber 145c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber start = pos + 1; 146c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber } 147c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber 148c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber return *this; 149c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber} 150c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber 1516b7f0700d3771e552964cf24ab9887275c310c4bYifan Hong#define FORMATTER_INPUT_INTEGER(__type__) \ 1526b7f0700d3771e552964cf24ab9887275c310c4bYifan Hong Formatter &Formatter::operator<<(__type__ n) { \ 1536b7f0700d3771e552964cf24ab9887275c310c4bYifan Hong return (*this) << std::to_string(n); \ 1546b7f0700d3771e552964cf24ab9887275c310c4bYifan Hong } \ 1556b7f0700d3771e552964cf24ab9887275c310c4bYifan Hong 1566b7f0700d3771e552964cf24ab9887275c310c4bYifan HongFORMATTER_INPUT_INTEGER(short); 1576b7f0700d3771e552964cf24ab9887275c310c4bYifan HongFORMATTER_INPUT_INTEGER(unsigned short); 1586b7f0700d3771e552964cf24ab9887275c310c4bYifan HongFORMATTER_INPUT_INTEGER(int); 1596b7f0700d3771e552964cf24ab9887275c310c4bYifan HongFORMATTER_INPUT_INTEGER(unsigned int); 1606b7f0700d3771e552964cf24ab9887275c310c4bYifan HongFORMATTER_INPUT_INTEGER(long); 1616b7f0700d3771e552964cf24ab9887275c310c4bYifan HongFORMATTER_INPUT_INTEGER(unsigned long); 1626b7f0700d3771e552964cf24ab9887275c310c4bYifan HongFORMATTER_INPUT_INTEGER(long long); 1636b7f0700d3771e552964cf24ab9887275c310c4bYifan HongFORMATTER_INPUT_INTEGER(unsigned long long); 1646b7f0700d3771e552964cf24ab9887275c310c4bYifan HongFORMATTER_INPUT_INTEGER(float); 1656b7f0700d3771e552964cf24ab9887275c310c4bYifan HongFORMATTER_INPUT_INTEGER(double); 1666b7f0700d3771e552964cf24ab9887275c310c4bYifan HongFORMATTER_INPUT_INTEGER(long double); 1676b7f0700d3771e552964cf24ab9887275c310c4bYifan Hong 1686b7f0700d3771e552964cf24ab9887275c310c4bYifan Hong#undef FORMATTER_INPUT_INTEGER 1696b7f0700d3771e552964cf24ab9887275c310c4bYifan Hong 1706b7f0700d3771e552964cf24ab9887275c310c4bYifan Hong#define FORMATTER_INPUT_CHAR(__type__) \ 1716b7f0700d3771e552964cf24ab9887275c310c4bYifan Hong Formatter &Formatter::operator<<(__type__ c) { \ 1726b7f0700d3771e552964cf24ab9887275c310c4bYifan Hong return (*this) << std::string(1, (char)c); \ 1736b7f0700d3771e552964cf24ab9887275c310c4bYifan Hong } \ 1746b7f0700d3771e552964cf24ab9887275c310c4bYifan Hong 1756b7f0700d3771e552964cf24ab9887275c310c4bYifan HongFORMATTER_INPUT_CHAR(char); 1766b7f0700d3771e552964cf24ab9887275c310c4bYifan HongFORMATTER_INPUT_CHAR(signed char); 1776b7f0700d3771e552964cf24ab9887275c310c4bYifan HongFORMATTER_INPUT_CHAR(unsigned char); 1786b7f0700d3771e552964cf24ab9887275c310c4bYifan Hong 1796b7f0700d3771e552964cf24ab9887275c310c4bYifan Hong#undef FORMATTER_INPUT_CHAR 180c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber 1810e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Hubervoid Formatter::setNamespace(const std::string &space) { 1820e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber mSpace = space; 1830e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber} 1840e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber 1850e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Hubervoid Formatter::output(const std::string &text) const { 1860e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber const size_t spaceLength = mSpace.size(); 1870e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber if (spaceLength > 0) { 1880e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber // Remove all occurences of "mSpace" and output the filtered result. 1890e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber size_t matchPos = text.find(mSpace); 1900e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber if (matchPos != std::string::npos) { 1910e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber std::string newText = text.substr(0, matchPos); 1920e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber size_t startPos = matchPos + spaceLength; 1930e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber while ((matchPos = text.find(mSpace, startPos)) 1940e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber != std::string::npos) { 1950e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber newText.append(text.substr(startPos, matchPos - startPos)); 1960e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber startPos = matchPos + spaceLength; 1970e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber } 1980e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber newText.append(text.substr(startPos)); 1990e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber fprintf(mFile, "%s", newText.c_str()); 2000e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber return; 2010e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber } 2020e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber } 2030e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber 2040e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber fprintf(mFile, "%s", text.c_str()); 2050e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber} 2060e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber 207c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber} // namespace android 208