1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     dbg_DebugString.cpp
4 
5   Copyright (C)2009 Nintendo Co., Ltd.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Rev: 35043 $
14  *---------------------------------------------------------------------------*/
15 
16 #include <cstdio>
17 #include <cstdarg>
18 #include <cstring>
19 
20 #include <nn/Result.h>
21 #include <nn/config.h>
22 #include <nn/dbg/dbg_DebugString.h>
23 #include <nn/dbg/dbg_Result.h>
24 #include <nn/svc.h>
25 #include <nn/nstd.h>
26 #include <nn/middleware.h>
27 
28 namespace nn { namespace dbg {
29     namespace detail {
30 
31         namespace
32         {
33             NN_DEFINE_MIDDLEWARE(s_UsePutString, "NINTENDO", "DebugPrint");
34         }
35 
PutString(const char * text,s32 length)36         NN_WEAK_SYMBOL void PutString(const char* text, s32 length)
37         {
38             NN_UTIL_REFER_SYMBOL(s_UsePutString);
39             nn::svc::OutputDebugString(text, length);
40         }
41 
PutString(const char * text)42         void PutString(const char* text)
43         {
44             PutString(text, std::strlen(text));
45         }
46 
VPrintf(const char * fmt,::std::va_list arg)47         NN_WEAK_SYMBOL void VPrintf(const char* fmt, ::std::va_list arg)
48         {
49             char buf[NN_DBG_PRINTF_BUFFER_LENGTH];
50             u32 length = ::std::vsnprintf(buf, sizeof(buf), fmt, arg);
51             if(length > NN_DBG_PRINTF_BUFFER_LENGTH)
52             {
53                 length = NN_DBG_PRINTF_BUFFER_LENGTH;
54             }
55             PutString(buf, length);
56         }
57 
TVPrintf(const char * fmt,::std::va_list arg)58         NN_WEAK_SYMBOL void TVPrintf(const char* fmt, ::std::va_list arg)
59         {
60             char buf[NN_DBG_TPRINTF_BUFFER_LENGTH];
61             u32 length = nstd::TVSNPrintf(buf, sizeof(buf), fmt, arg);
62             if(length > NN_DBG_TPRINTF_BUFFER_LENGTH)
63             {
64                 length = NN_DBG_TPRINTF_BUFFER_LENGTH;
65             }
66             PutString(buf, length);
67         }
68 
Printf(const char * fmt,...)69         /*NN_WEAK_SYMBOL*/ void Printf(const char* fmt, ...)
70         {
71             va_list vlist;
72 
73             va_start(vlist, fmt);
74             nn::dbg::detail::VPrintf(fmt, vlist);
75             va_end(vlist);
76         }
77 
TPrintf(const char * fmt,...)78         /*NN_WEAK_SYMBOL*/ void TPrintf(const char* fmt, ...)
79         {
80             va_list vlist;
81 
82             va_start(vlist, fmt);
83             nn::dbg::detail::TVPrintf(fmt, vlist);
84             va_end(vlist);
85         }
86 
87     }
88 }}
89 
90 
91 extern "C" {
92 
nndbgDetailPrintf(const char * fmt,...)93     /*NN_WEAK_SYMBOL*/ void nndbgDetailPrintf(const char* fmt, ...)
94     {
95         va_list vlist;
96 
97         va_start(vlist, fmt);
98         nn::dbg::detail::VPrintf(fmt, vlist);
99         va_end(vlist);
100     }
101 
nndbgDetailTPrintf(const char * fmt,...)102     /*NN_WEAK_SYMBOL*/ void nndbgDetailTPrintf(const char* fmt, ...)
103     {
104         va_list vlist;
105 
106         va_start(vlist, fmt);
107         nn::dbg::detail::TVPrintf(fmt, vlist);
108         va_end(vlist);
109     }
110 
nndbgDetailVPrintf(const char * fmt,va_list arg)111     NN_WEAK_SYMBOL void nndbgDetailVPrintf(const char* fmt, va_list arg)
112     {
113         nn::dbg::detail::VPrintf(fmt, arg);
114     }
115 
nndbgDetailTVPrintf(const char * fmt,va_list arg)116     NN_WEAK_SYMBOL void nndbgDetailTVPrintf(const char* fmt, va_list arg)
117     {
118         nn::dbg::detail::TVPrintf(fmt, arg);
119     }
120 
nndbgDetailPutString(const char * text,s32 length)121     NN_WEAK_SYMBOL void nndbgDetailPutString(const char* text, s32 length)
122     {
123         nn::dbg::detail::PutString(text, length);
124     }
125 
nndbgAssertionFailureHandler(bool print,const char * filename,int lineno,const char * fmt,...)126     NN_WEAK_SYMBOL int nndbgAssertionFailureHandler(bool print, const char* filename, int lineno, const char* fmt, ...)
127     {
128         va_list vlist;
129 
130         if (print)
131         {
132             nndbgDetailPrintf("Failed assertion at %s:%d\n  ", filename, lineno);
133 
134             va_start(vlist, fmt);
135             nndbgDetailVPrintf(fmt, vlist);
136             va_end(vlist);
137 
138             nndbgDetailPrintf("\n");
139         }
140         else
141         {
142             NN_UNUSED_VAR(filename);
143             NN_UNUSED_VAR(lineno);
144             NN_UNUSED_VAR(fmt);
145         }
146 
147         nn::dbg::Break(nn::dbg::BREAK_REASON_ASSERT);
148 
149         return 0;
150     }
151 
nndbgTAssertionFailureHandler(bool print,const char * filename,int lineno,const char * fmt,...)152     NN_WEAK_SYMBOL int nndbgTAssertionFailureHandler(bool print, const char* filename, int lineno, const char* fmt, ...)
153     {
154         va_list vlist;
155 
156         if (print)
157         {
158             nndbgDetailTPrintf("Failed assertion at %s:%d\n  ", filename, lineno);
159 
160             va_start(vlist, fmt);
161             nndbgDetailTVPrintf(fmt, vlist);
162             va_end(vlist);
163 
164             nndbgDetailTPrintf("\n");
165         }
166         else
167         {
168             NN_UNUSED_VAR(filename);
169             NN_UNUSED_VAR(lineno);
170             NN_UNUSED_VAR(fmt);
171         }
172 
173         nn::dbg::Break(nn::dbg::BREAK_REASON_ASSERT);
174 
175         return 0;
176     }
177 
178 }
179