1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "printer.h" 18 19 #include <unistd.h> 20 #include <stdlib.h> 21 #include <string.h> 22 #include <stdarg.h> 23 24 #define INITIAL_BUF_SIZE (16*1024) 25 26 char const* SPACES = " "; 27 const int SPACE_COUNT = strlen(SPACES); 28 29 Out::Out(int fd) 30 :mOut(fd == STDOUT_FILENO ? stdout : fdopen(fd, "w")), 31 mBufSize(INITIAL_BUF_SIZE), 32 mBuf((char*)malloc(INITIAL_BUF_SIZE)), 33 mIndent(0), 34 mPendingIndent(false) 35 { 36 } 37 38 Out::~Out() 39 { 40 fclose(mOut); 41 } 42 43 int 44 Out::reallocate(int size) 45 { 46 if (size > mBufSize) { 47 char* p = (char*)malloc(size); 48 if (p != NULL) { 49 free(mBuf); 50 mBufSize = size; 51 mBuf = p; 52 return size; 53 } 54 } 55 return mBufSize; 56 } 57 58 void 59 Out::printf(const char* format, ...) 60 { 61 if (mPendingIndent) { 62 print_indent(); 63 mPendingIndent = false; 64 } 65 66 int len; 67 68 va_list args; 69 va_start(args, format); 70 71 len = vsnprintf(mBuf, mBufSize, format, args); 72 va_end(args); 73 74 va_start(args, format); 75 len = vsnprintf(mBuf, mBufSize, format, args); 76 va_end(args); 77 78 if (len > 0) { 79 if (mIndent == 0) { 80 fwrite(mBuf, len, 1, mOut); 81 } else { 82 char* last = mBuf; 83 char* p; 84 do { 85 p = strchr(last, '\n'); 86 int size = p != NULL ? p - last + 1 : strlen(last); 87 fwrite(last, size, 1, mOut); 88 if (p != NULL) { 89 if (p[1] == '\0') { 90 mPendingIndent = true; 91 } else { 92 print_indent(); 93 } 94 } 95 last = p+1; 96 } while (p != NULL); 97 } 98 } 99 } 100 101 void 102 Out::indent() 103 { 104 mPendingIndent = true; 105 mIndent += 2; 106 } 107 108 void 109 Out::dedent() 110 { 111 if (mIndent > 0) { 112 mIndent -= 2; 113 } 114 } 115 116 void 117 Out::print_indent() 118 { 119 #if 0 120 fprintf(mOut, "[%d]", mIndent); 121 #else 122 int indent = mIndent; 123 while (indent > SPACE_COUNT) { 124 fwrite(SPACES, SPACE_COUNT, 1, mOut); 125 indent -= SPACE_COUNT; 126 } 127 fwrite(SPACES + SPACE_COUNT - indent, indent, 1, mOut); 128 #endif 129 } 130