1 | // Licensed to the .NET Foundation under one or more agreements. |
2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | // See the LICENSE file in the project root for more information. |
4 | |
5 | // |
6 | /******************************************************************************/ |
7 | /* dasm_formatType.cpp */ |
8 | /******************************************************************************/ |
9 | #include "ildasmpch.h" |
10 | |
11 | #include "formattype.h" |
12 | |
13 | BOOL g_fQuoteAllNames = FALSE; // used by ILDASM |
14 | BOOL g_fDumpTokens = FALSE; // used by ILDASM |
15 | LPCSTR *rAsmRefName = NULL; // used by ILDASM |
16 | ULONG ulNumAsmRefs = 0; // used by ILDASM |
17 | BOOL g_fDumpRTF = FALSE; // used by ILDASM |
18 | BOOL g_fDumpHTML = FALSE; // used by ILDASM |
19 | BOOL g_fUseProperName = FALSE; // used by ILDASM |
20 | DynamicArray<mdToken> *g_dups = NULL; // used by ILDASM |
21 | DWORD g_NumDups=0; // used by ILDASM |
22 | DynamicArray<TypeDefDescr> *g_typedefs = NULL; // used by ILDASM |
23 | DWORD g_NumTypedefs=0; // used by ILDASM |
24 | |
25 | // buffers created in Init and deleted in Uninit (dasm.cpp) |
26 | CQuickBytes * g_szBuf_KEYWORD = NULL; |
27 | CQuickBytes * = NULL; |
28 | CQuickBytes * g_szBuf_ERRORMSG = NULL; |
29 | CQuickBytes * g_szBuf_ANCHORPT = NULL; |
30 | CQuickBytes * g_szBuf_JUMPPT = NULL; |
31 | CQuickBytes * g_szBuf_UnquotedProperName = NULL; |
32 | CQuickBytes * g_szBuf_ProperName = NULL; |
33 | |
34 | // Protection against null names, used by ILDASM |
35 | const char * const szStdNamePrefix[] = {"MO" ,"TR" ,"TD" ,"" ,"FD" ,"" ,"MD" ,"" ,"PA" ,"II" ,"MR" ,"" ,"CA" ,"" ,"PE" ,"" ,"" ,"SG" ,"" ,"" ,"EV" , |
36 | "" ,"" ,"PR" ,"" ,"" ,"MOR" ,"TS" ,"" ,"" ,"" ,"" ,"AS" ,"" ,"" ,"AR" ,"" ,"" ,"FL" ,"ET" ,"MAR" }; |
37 | |
38 | //------------------------------------------------------------------------------- |
39 | // Reference analysis (ILDASM) |
40 | DynamicArray<TokPair> *g_refs = NULL; |
41 | DWORD g_NumRefs=0; |
42 | mdToken g_tkRefUser=0; // for PrettyPrintSig |
43 | |
44 | mdToken g_tkVarOwner = 0; |
45 | mdToken g_tkMVarOwner = 0; |
46 | |
47 | // Include the shared formatting routines |
48 | #include "formattype.cpp" |
49 | |
50 | // Special dumping routines for keywords, comments and errors, used by ILDASM |
51 | |
52 | const char* KEYWORD(__in_opt __nullterminated const char* szOrig) |
53 | { |
54 | CONTRACTL |
55 | { |
56 | THROWS; |
57 | GC_NOTRIGGER; |
58 | } |
59 | CONTRACTL_END; |
60 | |
61 | const char* szPrefix = "" ; |
62 | const char* szPostfix = "" ; |
63 | if(g_fDumpHTML) |
64 | { |
65 | szPrefix = "<B><FONT COLOR=NAVY>" ; |
66 | szPostfix = "</FONT></B>" ; |
67 | } |
68 | else if(g_fDumpRTF) |
69 | { |
70 | szPrefix = "\\b\\cf1 " ; |
71 | szPostfix = "\\cf0\\b0 " ; |
72 | } |
73 | if(szOrig == NULL) return szPrefix; |
74 | if(szOrig == (char*)-1) return szPostfix; |
75 | if(*szPrefix) |
76 | { |
77 | g_szBuf_KEYWORD->Shrink(0); |
78 | appendStr(g_szBuf_KEYWORD,szPrefix); |
79 | appendStr(g_szBuf_KEYWORD,szOrig); |
80 | appendStr(g_szBuf_KEYWORD,szPostfix); |
81 | return asString(g_szBuf_KEYWORD); |
82 | } |
83 | else |
84 | return szOrig; |
85 | } |
86 | const char* (__in_opt __nullterminated const char* szOrig) |
87 | { |
88 | CONTRACTL |
89 | { |
90 | THROWS; |
91 | GC_NOTRIGGER; |
92 | } |
93 | CONTRACTL_END; |
94 | |
95 | const char* szPrefix = "" ; |
96 | const char* szPostfix = "" ; |
97 | if(g_fDumpHTML) |
98 | { |
99 | szPrefix = "<I><FONT COLOR=GREEN>" ; |
100 | szPostfix = "</FONT></I>" ; |
101 | } |
102 | else if(g_fDumpRTF) |
103 | { |
104 | szPrefix = "\\cf2\\i " ; |
105 | szPostfix = "\\i0\\cf0 " ; |
106 | } |
107 | else |
108 | { |
109 | szPrefix = "" ; |
110 | szPostfix = "" ; |
111 | } |
112 | if(szOrig == NULL) return szPrefix; |
113 | if(szOrig == (char*)-1) return szPostfix; |
114 | if(*szPrefix) |
115 | { |
116 | g_szBuf_COMMENT->Shrink(0); |
117 | appendStr(g_szBuf_COMMENT,szPrefix); |
118 | appendStr(g_szBuf_COMMENT,szOrig); |
119 | appendStr(g_szBuf_COMMENT,szPostfix); |
120 | return asString(g_szBuf_COMMENT); |
121 | } |
122 | else |
123 | return szOrig; |
124 | } |
125 | const char* ERRORMSG(__in_opt __nullterminated const char* szOrig) |
126 | { |
127 | CONTRACTL |
128 | { |
129 | THROWS; |
130 | GC_NOTRIGGER; |
131 | } |
132 | CONTRACTL_END; |
133 | |
134 | const char* szPrefix = "" ; |
135 | const char* szPostfix = "" ; |
136 | if(g_fDumpHTML) |
137 | { |
138 | szPrefix = "<I><B><FONT COLOR=RED>" ; |
139 | szPostfix = "</FONT></B></I>" ; |
140 | } |
141 | else if(g_fDumpRTF) |
142 | { |
143 | szPrefix = "\\cf3\\i\\b " ; |
144 | szPostfix = "\\cf0\\b0\\i0 " ; |
145 | } |
146 | if(szOrig == NULL) return szPrefix; |
147 | if(szOrig == (char*)-1) return szPostfix; |
148 | if(*szPrefix) |
149 | { |
150 | g_szBuf_ERRORMSG->Shrink(0); |
151 | appendStr(g_szBuf_ERRORMSG,szPrefix); |
152 | appendStr(g_szBuf_ERRORMSG,szOrig); |
153 | appendStr(g_szBuf_ERRORMSG,szPostfix); |
154 | return asString(g_szBuf_ERRORMSG); |
155 | } |
156 | else |
157 | return szOrig; |
158 | } |
159 | |
160 | const char* ANCHORPT(__in __nullterminated const char* szOrig, mdToken tk) |
161 | { |
162 | CONTRACTL |
163 | { |
164 | THROWS; |
165 | GC_NOTRIGGER; |
166 | } |
167 | CONTRACTL_END; |
168 | |
169 | if(g_fDumpHTML) |
170 | { |
171 | char szPrefix[64]; |
172 | const char* szPostfix = "</A>" ; |
173 | sprintf_s(szPrefix, COUNTOF(szPrefix), "<A NAME=A%08X>" ,tk); |
174 | g_szBuf_ANCHORPT->Shrink(0); |
175 | appendStr(g_szBuf_ANCHORPT,szPrefix); |
176 | appendStr(g_szBuf_ANCHORPT,szOrig); |
177 | appendStr(g_szBuf_ANCHORPT,szPostfix); |
178 | return asString(g_szBuf_ANCHORPT); |
179 | } |
180 | else |
181 | return szOrig; |
182 | } |
183 | const char* JUMPPT(__in __nullterminated const char* szOrig, mdToken tk) |
184 | { |
185 | CONTRACTL |
186 | { |
187 | THROWS; |
188 | GC_NOTRIGGER; |
189 | } |
190 | CONTRACTL_END; |
191 | |
192 | if(g_fDumpHTML) |
193 | { |
194 | char szPrefix[64]; |
195 | const char* szPostfix = "</A>" ; |
196 | sprintf_s(szPrefix,COUNTOF(szPrefix), "<A HREF=#A%08X>" ,tk); |
197 | g_szBuf_JUMPPT->Shrink(0); |
198 | appendStr(g_szBuf_JUMPPT,szPrefix); |
199 | appendStr(g_szBuf_JUMPPT,szOrig); |
200 | appendStr(g_szBuf_JUMPPT,szPostfix); |
201 | return asString(g_szBuf_JUMPPT); |
202 | } |
203 | else |
204 | return szOrig; |
205 | } |
206 | const char* SCOPE(void) { return g_fDumpRTF ? "\\{" : "{" ; } |
207 | const char* UNSCOPE(void) { return g_fDumpRTF ? "\\}" : "}" ; } |
208 | const char* LTN(void) { return g_fDumpHTML ? "<" : "<" ; } |
209 | const char* GTN(void) { return g_fDumpHTML ? ">" : ">" ; } |
210 | const char* AMP(void) { return g_fDumpHTML ? "&" : "&" ; } |
211 | |
212 | |
213 | |
214 | /******************************************************************************/ |
215 | // Function: convert spec.symbols to esc sequences and single-quote if necessary |
216 | const char* UnquotedProperName(__in __nullterminated const char* name, unsigned len/*=(unsigned)-1*/) |
217 | { |
218 | CONTRACTL |
219 | { |
220 | THROWS; |
221 | GC_NOTRIGGER; |
222 | } |
223 | CONTRACTL_END; |
224 | |
225 | CQuickBytes *buff = g_szBuf_UnquotedProperName; |
226 | _ASSERTE (buff); |
227 | if(g_fUseProperName) |
228 | { |
229 | const char *pcn,*pcend,*ret; |
230 | if (name != NULL) |
231 | { |
232 | if (*name != 0) |
233 | { |
234 | pcn = name; |
235 | if (len == (unsigned)(-1)) |
236 | len = (unsigned)strlen(name); |
237 | pcend = pcn + len; |
238 | buff->Shrink(0); |
239 | for (pcn = name; pcn < pcend; pcn++) |
240 | { |
241 | switch(*pcn) |
242 | { |
243 | case '\t': appendChar(buff,'\\'); appendChar(buff,'t'); break; |
244 | case '\n': appendChar(buff,'\\'); appendChar(buff,'n'); break; |
245 | case '\b': appendChar(buff,'\\'); appendChar(buff,'b'); break; |
246 | case '\r': appendChar(buff,'\\'); appendChar(buff,'r'); break; |
247 | case '\f': appendChar(buff,'\\'); appendChar(buff,'f'); break; |
248 | case '\v': appendChar(buff,'\\'); appendChar(buff,'v'); break; |
249 | case '\a': appendChar(buff,'\\'); appendChar(buff,'a'); break; |
250 | case '\\': appendChar(buff,'\\'); appendChar(buff,'\\'); break; |
251 | case '\'': appendChar(buff,'\\'); appendChar(buff,'\''); break; |
252 | case '\"': appendChar(buff,'\\'); appendChar(buff,'\"'); break; |
253 | case '{': appendStr(buff,SCOPE()); break; |
254 | case '}': appendStr(buff,UNSCOPE()); break; |
255 | case '<': appendStr(buff,LTN()); break; |
256 | case '>': appendStr(buff,GTN()); break; |
257 | case '&': appendStr(buff,AMP()); break; |
258 | default: appendChar(buff,*pcn); |
259 | } |
260 | } |
261 | ret = asString(buff); |
262 | } |
263 | else ret = "" ; |
264 | } |
265 | else ret = NULL; |
266 | return ret; |
267 | } |
268 | return name; |
269 | } |
270 | /******************************************************************************/ |
271 | // Function: convert spec.symbols to esc sequences and single-quote if necessary |
272 | const char* ProperName(__in __nullterminated const char* name, bool isLocalName) |
273 | { |
274 | CONTRACTL |
275 | { |
276 | THROWS; |
277 | GC_NOTRIGGER; |
278 | } |
279 | CONTRACTL_END; |
280 | |
281 | CQuickBytes *buff = g_szBuf_ProperName; |
282 | _ASSERTE (buff); |
283 | if(g_fUseProperName) |
284 | { |
285 | const char *ret; |
286 | BOOL fQuoted; |
287 | if(name) |
288 | { |
289 | if(*name) |
290 | { |
291 | buff->Shrink(0); |
292 | fQuoted = isLocalName ? IsLocalToQuote(name) : IsNameToQuote(name); |
293 | if(fQuoted) appendChar(buff,'\''); |
294 | appendStr(buff,UnquotedProperName(name)); |
295 | if(fQuoted) appendChar(buff,'\''); |
296 | ret = asString(buff); |
297 | } |
298 | else ret = "" ; |
299 | } |
300 | else ret = NULL; |
301 | return ret; |
302 | } |
303 | return name; |
304 | } |
305 | |