summaryrefslogtreecommitdiff
path: root/tools/incident_report/printer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/incident_report/printer.cpp')
-rw-r--r--tools/incident_report/printer.cpp127
1 files changed, 127 insertions, 0 deletions
diff --git a/tools/incident_report/printer.cpp b/tools/incident_report/printer.cpp
new file mode 100644
index 000000000000..1ab6bd87913e
--- /dev/null
+++ b/tools/incident_report/printer.cpp
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include "printer.h"
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define INITIAL_BUF_SIZE (16*1024)
+
+char const* SPACES = " ";
+const int SPACE_COUNT = strlen(SPACES);
+
+Out::Out(int fd)
+ :mOut(fd == STDOUT_FILENO ? stdout : fdopen(fd, "w")),
+ mBufSize(INITIAL_BUF_SIZE),
+ mBuf((char*)malloc(INITIAL_BUF_SIZE)),
+ mIndent(0),
+ mPendingIndent(false)
+{
+}
+
+Out::~Out()
+{
+ fclose(mOut);
+}
+
+int
+Out::reallocate(int size)
+{
+ if (size > mBufSize) {
+ char* p = (char*)malloc(size);
+ if (p != NULL) {
+ free(mBuf);
+ mBufSize = size;
+ mBuf = p;
+ return size;
+ }
+ }
+ return mBufSize;
+}
+
+void
+Out::printf(const char* format, ...)
+{
+ if (mPendingIndent) {
+ print_indent();
+ mPendingIndent = false;
+ }
+
+ int len;
+
+ va_list args;
+ va_start(args, format);
+
+ len = vsnprintf(mBuf, mBufSize, format, args);
+ bool truncated = (len >= mBufSize) && (reallocate(len) < len);
+
+ len = vsnprintf(mBuf, mBufSize, format, args);
+ va_end(args);
+
+ if (len > 0) {
+ if (mIndent == 0) {
+ fwrite(mBuf, len, 1, mOut);
+ } else {
+ char* last = mBuf;
+ char* p;
+ do {
+ p = strchr(last, '\n');
+ int size = p != NULL ? p - last + 1 : strlen(last);
+ fwrite(last, size, 1, mOut);
+ if (p != NULL) {
+ if (p[1] == '\0') {
+ mPendingIndent = true;
+ } else {
+ print_indent();
+ }
+ }
+ last = p+1;
+ } while (p != NULL);
+ }
+ }
+}
+
+void
+Out::indent()
+{
+ mPendingIndent = true;
+ mIndent += 2;
+}
+
+void
+Out::dedent()
+{
+ if (mIndent > 0) {
+ mIndent -= 2;
+ }
+}
+
+void
+Out::print_indent()
+{
+#if 0
+ fprintf(mOut, "[%d]", mIndent);
+#else
+ int indent = mIndent;
+ while (indent > SPACE_COUNT) {
+ fwrite(SPACES, SPACE_COUNT, 1, mOut);
+ indent -= SPACE_COUNT;
+ }
+ fwrite(SPACES + SPACE_COUNT - indent, indent, 1, mOut);
+#endif
+}