1// Copyright 2016 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <printf.h>
6#include <xefi.h>
7
8#define PCBUFMAX 126
9// buffer is two larger to leave room for a \0 and room
10// for a \r that may be added after a \n
11
12typedef struct {
13    int off;
14    char16_t buf[PCBUFMAX + 2];
15} _pcstate;
16
17static int _printf_console_out(const char* str, size_t len, void* _state) {
18    _pcstate* state = _state;
19    char16_t* buf = state->buf;
20    int i = state->off;
21    int n = len;
22    while (n > 0) {
23        if (*str == '\n') {
24            buf[i++] = '\r';
25        }
26        buf[i++] = *str++;
27        if (i >= PCBUFMAX) {
28            buf[i] = 0;
29            gConOut->OutputString(gConOut, buf);
30            i = 0;
31        }
32        n--;
33    }
34    state->off = i;
35    return len;
36}
37
38int _printf(const char* fmt, ...) {
39    va_list ap;
40    _pcstate state;
41    int r;
42    state.off = 0;
43    va_start(ap, fmt);
44    r = _printf_engine(_printf_console_out, &state, fmt, ap);
45    va_end(ap);
46    if (state.off) {
47        state.buf[state.off] = 0;
48        gConOut->OutputString(gConOut, state.buf);
49    }
50    return r;
51}
52
53int puts16(char16_t* str) {
54    return gConOut->OutputString(gConOut, str) == EFI_SUCCESS ? 0 : -1;
55}
56