11754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato/*
21754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * Copyright (C) 2016 The Android Open Source Project
31754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato *
41754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * Licensed under the Apache License, Version 2.0 (the "License");
51754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * you may not use this file except in compliance with the License.
61754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * You may obtain a copy of the License at
71754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato *
81754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato *      http://www.apache.org/licenses/LICENSE-2.0
91754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato *
101754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * Unless required by applicable law or agreed to in writing, software
111754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * distributed under the License is distributed on an "AS IS" BASIS,
121754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * See the License for the specific language governing permissions and
141754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * limitations under the License.
151754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato */
161754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
171754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include "printer.h"
181754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
191754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <unistd.h>
201754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <stdlib.h>
211754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <string.h>
22b69b95f0bd8ce69761cad878629edaab6ac17443Joe Onorato#include <stdarg.h>
231754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
241754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#define INITIAL_BUF_SIZE (16*1024)
251754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
261754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratochar const* SPACES = "                                                            ";
271754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratoconst int SPACE_COUNT = strlen(SPACES);
281754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
291754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe OnoratoOut::Out(int fd)
301754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    :mOut(fd == STDOUT_FILENO ? stdout : fdopen(fd, "w")),
311754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato     mBufSize(INITIAL_BUF_SIZE),
321754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato     mBuf((char*)malloc(INITIAL_BUF_SIZE)),
331754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato     mIndent(0),
341754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato     mPendingIndent(false)
351754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato{
361754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato}
371754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
381754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe OnoratoOut::~Out()
391754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato{
401754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    fclose(mOut);
411754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato}
421754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
431754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratoint
441754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe OnoratoOut::reallocate(int size)
451754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato{
461754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    if (size > mBufSize) {
471754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        char* p = (char*)malloc(size);
481754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        if (p != NULL) {
491754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato            free(mBuf);
501754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato            mBufSize = size;
511754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato            mBuf = p;
521754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato            return size;
531754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        }
541754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    }
551754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    return mBufSize;
561754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato}
571754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
581754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratovoid
591754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe OnoratoOut::printf(const char* format, ...)
601754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato{
611754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    if (mPendingIndent) {
621754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        print_indent();
631754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        mPendingIndent = false;
641754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    }
651754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
661754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    int len;
671754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
681754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    va_list args;
691754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    va_start(args, format);
701754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
711754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    len = vsnprintf(mBuf, mBufSize, format, args);
725a991adaf5a362761b2600af34989f38fbfc74ecJoe Onorato    va_end(args);
735a991adaf5a362761b2600af34989f38fbfc74ecJoe Onorato
745a991adaf5a362761b2600af34989f38fbfc74ecJoe Onorato    va_start(args, format);
751754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    len = vsnprintf(mBuf, mBufSize, format, args);
761754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    va_end(args);
771754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
781754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    if (len > 0) {
791754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        if (mIndent == 0) {
801754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato            fwrite(mBuf, len, 1, mOut);
811754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        } else {
821754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato            char* last = mBuf;
831754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato            char* p;
841754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato            do {
851754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                p = strchr(last, '\n');
861754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                int size = p != NULL ? p - last + 1 : strlen(last);
871754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                fwrite(last, size, 1, mOut);
881754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                if (p != NULL) {
891754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                    if (p[1] == '\0') {
901754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                        mPendingIndent = true;
911754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                    } else {
921754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                        print_indent();
931754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                    }
941754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                }
951754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                last = p+1;
961754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato            } while (p != NULL);
971754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        }
981754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    }
991754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato}
1001754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
1011754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratovoid
1021754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe OnoratoOut::indent()
1031754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato{
1041754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    mPendingIndent = true;
1051754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    mIndent += 2;
1061754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato}
1071754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
1081754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratovoid
1091754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe OnoratoOut::dedent()
1101754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato{
1111754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    if (mIndent > 0) {
1121754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        mIndent -= 2;
1131754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    }
1141754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato}
1151754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
1161754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratovoid
1171754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe OnoratoOut::print_indent()
1181754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato{
1191754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#if 0
1201754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    fprintf(mOut, "[%d]", mIndent);
1211754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#else
1221754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    int indent = mIndent;
1231754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    while (indent > SPACE_COUNT) {
1241754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        fwrite(SPACES, SPACE_COUNT, 1, mOut);
1251754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        indent -= SPACE_COUNT;
1261754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    }
1271754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    fwrite(SPACES + SPACE_COUNT - indent, indent, 1, mOut);
1281754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#endif
1291754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato}
130