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: 28522 $
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 
nndbgAssertionFailureHandler(bool print,const char * filename,int lineno,const char * fmt,...)121     NN_WEAK_SYMBOL int nndbgAssertionFailureHandler(bool print, const char* filename, int lineno, const char* fmt, ...)
122     {
123         va_list vlist;
124 
125         if (print)
126         {
127             nndbgDetailPrintf("Failed assertion at %s:%d\n  ", filename, lineno);
128 
129             va_start(vlist, fmt);
130             nndbgDetailVPrintf(fmt, vlist);
131             va_end(vlist);
132 
133             nndbgDetailPrintf("\n");
134         }
135         else
136         {
137             NN_UNUSED_VAR(filename);
138             NN_UNUSED_VAR(lineno);
139             NN_UNUSED_VAR(fmt);
140         }
141 
142         nn::dbg::Break(nn::dbg::BREAK_REASON_ASSERT);
143 
144         return 0;
145     }
146 
nndbgTAssertionFailureHandler(bool print,const char * filename,int lineno,const char * fmt,...)147     NN_WEAK_SYMBOL int nndbgTAssertionFailureHandler(bool print, const char* filename, int lineno, const char* fmt, ...)
148     {
149         va_list vlist;
150 
151         if (print)
152         {
153             nndbgDetailTPrintf("Failed assertion at %s:%d\n  ", filename, lineno);
154 
155             va_start(vlist, fmt);
156             nndbgDetailTVPrintf(fmt, vlist);
157             va_end(vlist);
158 
159             nndbgDetailTPrintf("\n");
160         }
161         else
162         {
163             NN_UNUSED_VAR(filename);
164             NN_UNUSED_VAR(lineno);
165             NN_UNUSED_VAR(fmt);
166         }
167 
168         nn::dbg::Break(nn::dbg::BREAK_REASON_ASSERT);
169 
170         return 0;
171     }
172 
173 }
174