|
1 /* |
|
2 * Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Debug library |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #define __DEBUG_THIS__ |
|
20 #include <nsmldebug.h> |
|
21 #undef __DEBUG_THIS__ |
|
22 |
|
23 #include <f32file.h> |
|
24 #include <s32file.h> |
|
25 #include <utf.h> |
|
26 #include <e32std.h> |
|
27 |
|
28 #ifdef __WINS__ |
|
29 _LIT( KNSmlDebugOutputName, "C:\\NSmlDebug.txt" ); |
|
30 _LIT( KNSmlDebugDumpName, "C:\\NSmlDebugDump.txt" ); |
|
31 #else |
|
32 // In emulator logs are written into D: (or E:) drive (easier to read them using PC) |
|
33 _LIT( KNSmlDebugOutputName, ":\\NSmlDebug.txt" ); |
|
34 _LIT( KNSmlDebugDumpName, ":\\NSmlDebugDump.txt" ); |
|
35 _LIT( KNSmlDebugDriveLetters, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); |
|
36 |
|
37 #endif |
|
38 |
|
39 _LIT( KNSmlDebugMutexName, "NSmlDebugMutex" ); |
|
40 _LIT( KNSmlDebugMutexNameDump, "NSmlDebugMutexDump" ); |
|
41 |
|
42 static const TInt KBufferSize = 512; |
|
43 |
|
44 #pragma warning (push) |
|
45 #pragma warning (disable : 4127) |
|
46 |
|
47 |
|
48 // -------------------------------------------------------------------------------- |
|
49 // void NSmlGrabMutexLC( RMutex& aMutex, const TDesC& aMutexName ) |
|
50 // -------------------------------------------------------------------------------- |
|
51 LOCAL_C void NSmlGrabMutexLC( RMutex& aMutex, const TDesC& aMutexName ) |
|
52 { |
|
53 while( ETrue ) |
|
54 { |
|
55 TInt ret = aMutex.CreateGlobal(aMutexName); |
|
56 if( ret == KErrNone ) // We created the mutex -> Issue wait() |
|
57 { |
|
58 aMutex.Wait(); |
|
59 break; |
|
60 } |
|
61 if( ret == KErrAlreadyExists ) // Mutex already existed -> Open it |
|
62 { |
|
63 ret = aMutex.OpenGlobal(aMutexName); |
|
64 if( ret == KErrNone ) // We got handle to the mutex -> Issue wait() |
|
65 { |
|
66 aMutex.Wait(); |
|
67 break; |
|
68 } |
|
69 } |
|
70 } |
|
71 CleanupClosePushL(aMutex); |
|
72 } |
|
73 |
|
74 #pragma warning (pop) |
|
75 |
|
76 // -------------------------------------------------------------------------------- |
|
77 // void DumpToFileL( TPtrC8 aBuffer ) |
|
78 // -------------------------------------------------------------------------------- |
|
79 void DumpToFileL( TPtrC8 aBuffer ) |
|
80 { |
|
81 RFs fileSession; |
|
82 TInt pushed(0); |
|
83 if( fileSession.Connect() == KErrNone ) |
|
84 { |
|
85 CleanupClosePushL(fileSession); |
|
86 pushed++; |
|
87 RFile file; |
|
88 #ifdef __WINS__ |
|
89 if( file.Open(fileSession, KNSmlDebugOutputName(), EFileShareAny|EFileWrite) == KErrNone ) |
|
90 #else |
|
91 HBufC* outputName = HBufC::NewLC( KNSmlDebugOutputName().Length()+1 ); |
|
92 pushed++; |
|
93 TPtr namePtr = outputName->Des(); |
|
94 TDriveInfo driveInfo; |
|
95 for ( TUint driveNumber = EDriveA; driveNumber <= EDriveZ; driveNumber++ ) |
|
96 { |
|
97 fileSession.Drive( driveInfo, driveNumber ); |
|
98 if ( KDriveAttRemovable & driveInfo.iDriveAtt ) |
|
99 { |
|
100 // this is MMC |
|
101 namePtr.Insert( 0, KNSmlDebugDriveLetters().Mid( driveNumber, 1 )); |
|
102 namePtr.Insert( 1, KNSmlDebugOutputName() ); |
|
103 break; |
|
104 } |
|
105 } |
|
106 if( file.Open(fileSession, *outputName, EFileShareAny|EFileWrite) == KErrNone ) |
|
107 #endif |
|
108 |
|
109 { |
|
110 CleanupClosePushL(file); |
|
111 TInt pos(0); |
|
112 file.Seek(ESeekEnd, pos); |
|
113 RMutex mutex; |
|
114 NSmlGrabMutexLC(mutex, KNSmlDebugMutexName()); |
|
115 TInt result = file.Write(aBuffer); |
|
116 TInt result2 = file.Flush(); |
|
117 mutex.Signal(); |
|
118 CleanupStack::PopAndDestroy(2); // file, mutex |
|
119 User::LeaveIfError(result); |
|
120 User::LeaveIfError(result2); |
|
121 } |
|
122 CleanupStack::PopAndDestroy( pushed ); // fileSession and (for target) outputName |
|
123 } |
|
124 } |
|
125 |
|
126 // -------------------------------------------------------------------------------- |
|
127 // void NSmlGetDateAndTimeL( TDes8& aDateBuffer, TDes8& aTimeBuffer ) |
|
128 // -------------------------------------------------------------------------------- |
|
129 LOCAL_C void NSmlGetDateAndTimeL( TDes8& aDateBuffer, TDes8& aTimeBuffer ) |
|
130 { |
|
131 TTime time; |
|
132 time.HomeTime(); |
|
133 HBufC* dateBuffer = HBufC::NewLC(64); |
|
134 TPtr ptrDateBuffer = dateBuffer->Des(); |
|
135 HBufC* timeBuffer = HBufC::NewLC(64); |
|
136 TPtr ptrTimeBuffer = timeBuffer->Des(); |
|
137 time.FormatL(ptrDateBuffer, _L("%D%M%Y%/0%1%/1%2%/2%3%/3")); |
|
138 time.FormatL(ptrTimeBuffer, _L("%-B%:0%J%:1%T%:2%S%.%*C4%:3%+B")); |
|
139 CnvUtfConverter::ConvertFromUnicodeToUtf8(aDateBuffer, ptrDateBuffer); |
|
140 CnvUtfConverter::ConvertFromUnicodeToUtf8(aTimeBuffer, ptrTimeBuffer); |
|
141 CleanupStack::PopAndDestroy(2); // dateBuffer, timeBuffer |
|
142 } |
|
143 |
|
144 // -------------------------------------------------------------------------------- |
|
145 // void doNSmlDebugInitL() - Windows compilation |
|
146 // -------------------------------------------------------------------------------- |
|
147 |
|
148 #ifdef __WINS__ |
|
149 |
|
150 void doNSmlDebugInitL() |
|
151 { |
|
152 RFs fileSession; |
|
153 User::LeaveIfError(fileSession.Connect()); |
|
154 CleanupClosePushL(fileSession); |
|
155 fileSession.Delete(KNSmlDebugOutputName()); |
|
156 fileSession.Delete(KNSmlDebugDumpName()); |
|
157 RFile file; |
|
158 |
|
159 #if !defined(__SML_DEVELOPER_DEBUG__) |
|
160 { |
|
161 User::LeaveIfError(file.Create(fileSession, KNSmlDebugOutputName(), EFileShareAny)); |
|
162 file.Close(); |
|
163 } |
|
164 #endif |
|
165 { |
|
166 User::LeaveIfError(file.Create(fileSession, KNSmlDebugDumpName(), EFileShareAny)); |
|
167 file.Close(); |
|
168 } |
|
169 CleanupStack::PopAndDestroy(); // fileSession |
|
170 } |
|
171 |
|
172 // -------------------------------------------------------------------------------- |
|
173 // void doNSmlDebugInitL() - Target compilation |
|
174 // -------------------------------------------------------------------------------- |
|
175 |
|
176 #else // #ifdef __WINS__ |
|
177 |
|
178 void doNSmlDebugInitL() |
|
179 { |
|
180 TInt pushed(0); |
|
181 RFs fileSession; |
|
182 User::LeaveIfError(fileSession.Connect()); |
|
183 CleanupClosePushL(fileSession); |
|
184 pushed++; |
|
185 |
|
186 TDriveInfo driveInfo; |
|
187 for ( TUint driveNumber = EDriveA; driveNumber <= EDriveZ; driveNumber++ ) |
|
188 { |
|
189 fileSession.Drive( driveInfo, driveNumber ); |
|
190 if ( KDriveAttRemovable & driveInfo.iDriveAtt ) |
|
191 { |
|
192 RFile file; |
|
193 HBufC* outputName = HBufC::NewLC( KNSmlDebugOutputName().Length()+1 ); |
|
194 pushed++; |
|
195 TPtr namePtr = outputName->Des(); |
|
196 namePtr.Insert( 0, KNSmlDebugDriveLetters().Mid( driveNumber, 1 )); |
|
197 namePtr.Insert( 1, KNSmlDebugOutputName() ); |
|
198 |
|
199 HBufC* outputDumpName = HBufC::NewLC( KNSmlDebugDumpName().Length()+1 ); |
|
200 pushed++; |
|
201 TPtr nameDumpPtr = outputDumpName->Des(); |
|
202 nameDumpPtr.Insert( 0, KNSmlDebugDriveLetters().Mid( driveNumber, 1 )); |
|
203 nameDumpPtr.Insert( 1, KNSmlDebugDumpName() ); |
|
204 |
|
205 fileSession.Delete(*outputName); |
|
206 fileSession.Delete(*outputDumpName); |
|
207 |
|
208 #if !defined(__SML_DEVELOPER_DEBUG__) |
|
209 { |
|
210 User::LeaveIfError(file.Create(fileSession, *outputName, EFileShareAny)); |
|
211 file.Close(); |
|
212 } |
|
213 #endif |
|
214 { |
|
215 User::LeaveIfError(file.Create(fileSession, *outputDumpName, EFileShareAny)); |
|
216 file.Close(); |
|
217 break; |
|
218 } |
|
219 } |
|
220 } |
|
221 CleanupStack::PopAndDestroy( pushed ); // fileSession |
|
222 } |
|
223 |
|
224 #endif |
|
225 |
|
226 |
|
227 // -------------------------------------------------------------------------------- |
|
228 // void NSmlDebugInitL() |
|
229 // -------------------------------------------------------------------------------- |
|
230 EXPORT_C void NSmlDebugInitL() |
|
231 { |
|
232 TInt err(KErrNone); |
|
233 TRAP(err, doNSmlDebugInitL()); |
|
234 } |
|
235 |
|
236 // -------------------------------------------------------------------------------- |
|
237 // void doNSmlDebugPrintL( TInt aCode, const TText8* aMsg, TBool aPrintToFile, TText8* aFile, TInt aLine ) |
|
238 // -------------------------------------------------------------------------------- |
|
239 void doNSmlDebugPrintL( TInt aCode, const TText8* aMsg, TBool aPrintToFile, TText8* aFile, TInt aLine ) |
|
240 { |
|
241 HBufC8* dateBuffer8 = HBufC8::NewLC(64); |
|
242 TPtr8 ptrDateBuffer8 = dateBuffer8->Des(); |
|
243 HBufC8* timeBuffer8 = HBufC8::NewLC(64); |
|
244 TPtr8 ptrTimeBuffer8 = timeBuffer8->Des(); |
|
245 |
|
246 NSmlGetDateAndTimeL(ptrDateBuffer8, ptrTimeBuffer8); |
|
247 TPtrC8 fileName(aFile); |
|
248 HBufC8* buffer8 = HBufC8::NewLC(KBufferSize); |
|
249 TPtr8 ptrBuffer8 = buffer8->Des(); |
|
250 TPtrC8 msg(aMsg); |
|
251 |
|
252 #if !defined(__SML_DEVELOPER_DEBUG__) |
|
253 ptrBuffer8.Format(_L8("[%S File: %S Line: %d] %S [Code: %d]\r\n"), &ptrTimeBuffer8, &fileName, aLine, &msg, aCode); |
|
254 #else |
|
255 ptrBuffer8.Format(_L8("[%S] %S\r\n"), &ptrTimeBuffer8, &msg); |
|
256 #endif |
|
257 |
|
258 if( aPrintToFile ) |
|
259 { |
|
260 DumpToFileL(ptrBuffer8); |
|
261 } |
|
262 else |
|
263 { |
|
264 HBufC* buffer = HBufC::NewLC(KBufferSize); |
|
265 TPtr ptrBuffer = buffer->Des(); |
|
266 CnvUtfConverter::ConvertToUnicodeFromUtf8(ptrBuffer, ptrBuffer8); |
|
267 User::InfoPrint(ptrBuffer); |
|
268 CleanupStack::PopAndDestroy(); // buffer |
|
269 } |
|
270 CleanupStack::PopAndDestroy(3); // buffer8, dateBuffer8, timeBuffer8 |
|
271 } |
|
272 |
|
273 // -------------------------------------------------------------------------------- |
|
274 // void NSmlDebugPrintL( const TText8* aMsg, TBool aPrintToFile, TText8* aFile, TInt aLine ) |
|
275 // -------------------------------------------------------------------------------- |
|
276 EXPORT_C void NSmlDebugPrintL( const TText8* aMsg, TBool aPrintToFile, TText8* aFile, TInt aLine ) |
|
277 { |
|
278 TInt err(KErrNone); |
|
279 TRAP(err, doNSmlDebugPrintL( 0, aMsg, aPrintToFile, aFile, aLine)); |
|
280 } |
|
281 |
|
282 // -------------------------------------------------------------------------------- |
|
283 // void NSmlDebugPrint_CodeL( TInt aCode, const TText8* aMsg, TBool aPrintToFile, TText8* aFile, TInt aLine ) |
|
284 // -------------------------------------------------------------------------------- |
|
285 EXPORT_C void NSmlDebugPrint_CodeL( TInt aCode, const TText8* aMsg, TBool aPrintToFile, TText8* aFile, TInt aLine ) |
|
286 { |
|
287 TInt err(KErrNone); |
|
288 TRAP(err, doNSmlDebugPrintL(aCode, aMsg, aPrintToFile, aFile, aLine)); |
|
289 } |
|
290 |
|
291 // -------------------------------------------------------------------------------- |
|
292 // void doNSmlDebugDumpL( void* aData, TInt aLength, TText8* aFile, TInt aLine, const TText8* aMsg ) |
|
293 // -------------------------------------------------------------------------------- |
|
294 void doNSmlDebugDumpL( void* aData, TInt aLength, TText8* aFile, TInt aLine, const TText8* aMsg ) |
|
295 { |
|
296 TInt pushed(0); |
|
297 HBufC8* pDateBuffer8 = HBufC8::NewLC(64); |
|
298 pushed++; |
|
299 TPtr8 dateBuffer8 = pDateBuffer8->Des(); |
|
300 HBufC8* pTimeBuffer8 = HBufC8::NewLC(64); |
|
301 pushed++; |
|
302 TPtr8 timeBuffer8 = pTimeBuffer8->Des(); |
|
303 NSmlGetDateAndTimeL(dateBuffer8, timeBuffer8); |
|
304 TPtrC8 data(REINTERPRET_CAST(TUint8*, aData), aLength); |
|
305 TPtrC8 fileName(aFile); |
|
306 HBufC8* buffer8 = HBufC8::NewLC(KBufferSize); |
|
307 pushed++; |
|
308 TPtr8 ptrBuffer8 = buffer8->Des(); |
|
309 TPtrC8 msg(aMsg); |
|
310 if( !msg.Length() ) |
|
311 { |
|
312 #if !defined(__SML_DEVELOPER_DEBUG__) |
|
313 ptrBuffer8.Format(_L8("[%S %S File: %S Line: %d Length: %d]\r\n"), &dateBuffer8, &timeBuffer8, &fileName, aLine, aLength); |
|
314 #else |
|
315 ptrBuffer8.Format(_L8("[%S %S Length: %d]\r\n"), &dateBuffer8, &timeBuffer8, aLength); |
|
316 #endif |
|
317 } |
|
318 else |
|
319 { |
|
320 #if !defined(__SML_DEVELOPER_DEBUG__) |
|
321 ptrBuffer8.Format(_L8("[%S %S File: %S Line: %d Length: %d] %S\r\n"), &dateBuffer8, &timeBuffer8, &fileName, aLine, aLength, &msg); |
|
322 #else |
|
323 ptrBuffer8.Format(_L8("[%S %S Length: %d] %S\r\n"), &dateBuffer8, &timeBuffer8, aLength, &msg); |
|
324 #endif |
|
325 } |
|
326 // Now we're ready to write into file |
|
327 RFs fileSession; |
|
328 if( fileSession.Connect() == KErrNone ) |
|
329 { |
|
330 CleanupClosePushL(fileSession); |
|
331 pushed++; |
|
332 RFile file; |
|
333 #ifdef __WINS__ |
|
334 if( file.Open(fileSession, KNSmlDebugDumpName(), EFileShareAny|EFileWrite) == KErrNone ) |
|
335 #else |
|
336 HBufC* outputDumpName = HBufC::NewLC( KNSmlDebugDumpName().Length()+1 ); |
|
337 pushed++; |
|
338 TPtr nameDumpPtr = outputDumpName->Des(); |
|
339 TDriveInfo driveInfo; |
|
340 for ( TUint driveNumber = EDriveA; driveNumber <= EDriveZ; driveNumber++ ) |
|
341 { |
|
342 fileSession.Drive( driveInfo, driveNumber ); |
|
343 if ( KDriveAttRemovable & driveInfo.iDriveAtt ) |
|
344 { |
|
345 // this is MMC |
|
346 nameDumpPtr.Insert( 0, KNSmlDebugDriveLetters().Mid( driveNumber, 1 )); |
|
347 nameDumpPtr.Insert( 1, KNSmlDebugDumpName() ); |
|
348 break; |
|
349 } |
|
350 } |
|
351 if( file.Open(fileSession, *outputDumpName, EFileShareAny|EFileWrite) == KErrNone ) |
|
352 #endif |
|
353 |
|
354 { |
|
355 CleanupClosePushL(file); |
|
356 TInt pos(0); |
|
357 file.Seek(ESeekEnd, pos); |
|
358 RMutex mutex; |
|
359 NSmlGrabMutexLC(mutex, KNSmlDebugMutexNameDump()); |
|
360 TInt result1 = file.Write(ptrBuffer8); |
|
361 TInt result2 = file.Write(data); |
|
362 TInt result3 = file.Write(_L8("\r\n\r\n")); |
|
363 TInt result4 = file.Flush(); |
|
364 mutex.Signal(); |
|
365 CleanupStack::PopAndDestroy(2); // file, mutex |
|
366 User::LeaveIfError(result1); |
|
367 User::LeaveIfError(result2); |
|
368 User::LeaveIfError(result3); |
|
369 User::LeaveIfError(result4); |
|
370 } |
|
371 } |
|
372 CleanupStack::PopAndDestroy( pushed ); // buffer8, pDateBuffer8, pTimeBuffer8 |
|
373 } |
|
374 |
|
375 // -------------------------------------------------------------------------------- |
|
376 // void NSmlDebugDumpL( void* aData, TInt aLength, TText8* aFile, TInt aLine, const TText8* aMsg ) |
|
377 // -------------------------------------------------------------------------------- |
|
378 EXPORT_C void NSmlDebugDumpL( void* aData, TInt aLength, TText8* aFile, TInt aLine, const TText8* aMsg ) |
|
379 { |
|
380 TInt err(KErrNone); |
|
381 TRAP(err, doNSmlDebugDumpL(aData, aLength, aFile, aLine, aMsg)); |
|
382 } |
|
383 |
|
384 // -------------------------------------------------------------------------------- |
|
385 // void NSmlDebugPrintHeaderL( TText8* aFile, TInt aLine ) |
|
386 // -------------------------------------------------------------------------------- |
|
387 void _NSmlDebugPrintHeaderL( TText8* aFile, TInt aLine ) |
|
388 { |
|
389 HBufC8* pDateBuffer8 = HBufC8::NewLC(64); |
|
390 TPtr8 dateBuffer8 = pDateBuffer8->Des(); |
|
391 HBufC8* pTimeBuffer8 = HBufC8::NewLC(64); |
|
392 TPtr8 timeBuffer8 = pTimeBuffer8->Des(); |
|
393 NSmlGetDateAndTimeL(dateBuffer8, timeBuffer8); |
|
394 TPtrC8 fileName(aFile); |
|
395 HBufC8* buffer8 = HBufC8::NewLC(KBufferSize); |
|
396 TPtr8 ptrBuffer8 = buffer8->Des(); |
|
397 #if !defined(__SML_DEVELOPER_DEBUG__) |
|
398 ptrBuffer8.Format(_L8("[%S File: %S Line: %d]"), &timeBuffer8, &fileName, aLine); |
|
399 #else |
|
400 ptrBuffer8.Format(_L8("[%S]"), &timeBuffer8); |
|
401 #endif |
|
402 ptrBuffer8.Append(_L8(" ")); |
|
403 DumpToFileL(ptrBuffer8); |
|
404 CleanupStack::PopAndDestroy(3); // buffer8, pDateBuffer, pTimeBuffer |
|
405 } |
|
406 |
|
407 EXPORT_C void NSmlDebugPrintHeaderL( TText8* aFile, TInt aLine ) |
|
408 { |
|
409 TInt err(KErrNone); |
|
410 TRAP(err, _NSmlDebugPrintHeaderL(aFile, aLine)); |
|
411 } |
|
412 |
|
413 // -------------------------------------------------------------------------------- |
|
414 // void NSmlDebugPrintArgs8L( TText8* aFmt, ... ) |
|
415 // -------------------------------------------------------------------------------- |
|
416 void _NSmlDebugPrintArgs8L( const TDesC8& aFmt, VA_LIST aList ) |
|
417 { |
|
418 HBufC8* pBuf = HBufC8::NewLC(1024*2); |
|
419 TPtr8 buf = pBuf->Des(); |
|
420 buf.FormatList(aFmt, aList); |
|
421 buf.Append(_L8("\r\n")); |
|
422 DumpToFileL(buf); |
|
423 CleanupStack::PopAndDestroy(); // pBuf |
|
424 } |
|
425 |
|
426 EXPORT_C void NSmlDebugPrintArgs8L( const TText8* aFmt, ... ) |
|
427 { |
|
428 VA_LIST args; |
|
429 VA_START (args, aFmt); |
|
430 TInt err(KErrNone); |
|
431 TRAP(err, _NSmlDebugPrintArgs8L(TPtrC8(aFmt), args)); |
|
432 VA_END(args); |
|
433 } |
|
434 |
|
435 // -------------------------------------------------------------------------------- |
|
436 // void NSmlDebugPrintArgs16L( TText8* aFmt, ... ) |
|
437 // -------------------------------------------------------------------------------- |
|
438 void _NSmlDebugPrintArgs16L( const TDesC16& aFmt, VA_LIST aList ) |
|
439 { |
|
440 HBufC16* buf = HBufC16::NewLC(1024*2); |
|
441 buf->Des().FormatList(aFmt, aList); |
|
442 HBufC8* pBuf8 = HBufC8::NewLC(1024*2); |
|
443 TPtr8 buf8 = pBuf8->Des(); |
|
444 buf8.Copy(*buf); |
|
445 buf8.Append(_L8("\r\n")); |
|
446 DumpToFileL(buf8); |
|
447 CleanupStack::PopAndDestroy(2); // buf, bBuf8 |
|
448 } |
|
449 |
|
450 EXPORT_C void NSmlDebugPrintArgs16L( const TText16* aFmt, ... ) |
|
451 { |
|
452 VA_LIST args; |
|
453 VA_START (args, aFmt); |
|
454 TInt err(KErrNone); |
|
455 TRAP(err, _NSmlDebugPrintArgs16L(TPtrC16(aFmt), args)); |
|
456 VA_END(args); |
|
457 } |
|
458 |
|
459 //End of File |
|
460 |