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 
12 typedef struct {
13     int off;
14     char16_t buf[PCBUFMAX + 2];
15 } _pcstate;
16 
_printf_console_out(const char * str,size_t len,void * _state)17 static 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 
_printf(const char * fmt,...)38 int _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 
puts16(char16_t * str)53 int puts16(char16_t* str) {
54     return gConOut->OutputString(gConOut, str) == EFI_SUCCESS ? 0 : -1;
55 }
56