|
1 /* |
|
2 * Copyright (c) 2010 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: |
|
15 * |
|
16 */ |
|
17 #include <nkern.h> |
|
18 |
|
19 #include "TraceCompilerTesterAdvanced.h" |
|
20 #include "TraceCompilerTesterCommon1.h" |
|
21 #include "TraceCompilerTesterCommon2.h" |
|
22 |
|
23 #include "OstTraceDefinitions.h" |
|
24 #ifdef OST_TRACE_COMPILER_IN_USE |
|
25 #include "TraceCompilerTesterAdvancedTraces.h" |
|
26 #include "TraceCompilerTesterCommon2Traces.h" |
|
27 #endif |
|
28 |
|
29 // Define group IDs. If TraceCompiler is missing, define these to get the code to compile. |
|
30 // However, component still won't work properly. |
|
31 #ifdef OST_TRACE_COMPILER_IN_USE |
|
32 #define SHORT_TRACE_TEST ASCII1 >> 16 |
|
33 #define LONG_TRACE_TEST ASCII300 >> 16 |
|
34 #define POINTER_PARAMETER_TEST POINTER_PARAMETER_TRACE1 >> 16 |
|
35 #define INCLUDED_NON_SOURCE_FILE_TEST HELLO_WORLD >> 16 |
|
36 #define TRACE_FLOW 0x7 |
|
37 #define KEKKONEN TEXT1 >> 16 |
|
38 #define TRACE_STATE 0x5 |
|
39 #define TRACE_DATA TRACE_DATA_TRACE >> 16 |
|
40 #define POST_CODE_TEST POST1 >> 16 |
|
41 #else |
|
42 #define SHORT_TRACE_TEST |
|
43 #define LONG_TRACE_TEST |
|
44 #define POINTER_PARAMETER_TEST |
|
45 #define INCLUDED_NON_SOURCE_FILE_TEST |
|
46 #define TRACE_FLOW |
|
47 #define KEKKONEN |
|
48 #define TRACE_STATE |
|
49 #define TRACE_DATA |
|
50 #define POST_CODE_TEST |
|
51 #endif |
|
52 |
|
53 |
|
54 //- Local constants --------------------------------------------------------- |
|
55 |
|
56 const TUint32 KComponentID = 0x20011111; |
|
57 |
|
58 _LIT8(buf1, "1"); |
|
59 _LIT8(buf2, "12"); |
|
60 _LIT8(buf3, "123"); |
|
61 _LIT8(buf4, "1234"); |
|
62 _LIT8(buf60, "123456789_123456789_123456789_123456789_123456789_123456789X"); |
|
63 _LIT8(buf300, "123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789X"); |
|
64 _LIT8(buf333, "123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_12X"); |
|
65 _LIT8(buf512, "123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789Y1X"); |
|
66 _LIT8(buf600, "123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789X"); |
|
67 |
|
68 //- Macros ------------------------------------------------------------------ |
|
69 |
|
70 |
|
71 //- Member Functions -------------------------------------------------------- |
|
72 |
|
73 /** |
|
74 * Constructor |
|
75 */ |
|
76 DTraceCompilerTesterAdvanced::DTraceCompilerTesterAdvanced() |
|
77 { |
|
78 } |
|
79 |
|
80 /** |
|
81 * EnergyMonitor Destructor |
|
82 */ |
|
83 DTraceCompilerTesterAdvanced::~DTraceCompilerTesterAdvanced() |
|
84 { |
|
85 } |
|
86 |
|
87 /** |
|
88 * EnergyMonitor second-phase constructor |
|
89 * |
|
90 * @param |
|
91 * @return System-wide error code |
|
92 */ |
|
93 TInt DTraceCompilerTesterAdvanced::Construct() |
|
94 { |
|
95 Kern::Printf( "-------------- DTraceCompilerTesterAdvanced::Construct ----------------" ); |
|
96 TInt ret( KErrNone ); |
|
97 |
|
98 // Register notification receiver by using just component ID |
|
99 RegisterNotificationReceiver( KComponentID); |
|
100 |
|
101 return ret; |
|
102 } |
|
103 |
|
104 /** |
|
105 * Callback function for Trace Activation |
|
106 * |
|
107 * @param aComponentId |
|
108 * @param aGroupId |
|
109 */ |
|
110 void DTraceCompilerTesterAdvanced::TraceActivated( TUint32 aComponentId, TUint16 aGroupId ) |
|
111 { |
|
112 |
|
113 Kern::Printf( "DTraceCompilerTesterAdvanced::TraceActivated - ComponentId = 0x%x, GroupId = 0x%x", aComponentId, aGroupId ); |
|
114 |
|
115 if (aGroupId == POINTER_PARAMETER_TEST) |
|
116 { |
|
117 // Print out pointer values of two NTimers by using %p tag |
|
118 Kern::Printf( "--------------TraceCompilerTesterAdvanced Pointer Parameter Test START----------------" ); |
|
119 NTimer* myNTimer1 = new NTimer(); |
|
120 NTimer* myNTimer2 = new NTimer(); |
|
121 const NTimer* myNTimer3 = new NTimer(); |
|
122 OstTraceExt2( POINTER_PARAMETER_TEST, POINTER_PARAMETER_TRACE1, "Print out pointer values of two NTimers;myNTimer1=%p;myNTimer2=%p", myNTimer1, myNTimer2 ); |
|
123 OstTraceExt1( POINTER_PARAMETER_TEST, POINTER_PARAMETER_TRACE2, "Print out pointer values of one const NTimers;myNTimer3=%p", myNTimer3 ); |
|
124 delete myNTimer1; |
|
125 delete myNTimer2; |
|
126 delete myNTimer3; |
|
127 Kern::Printf( "--------------TraceCompilerTesterAdvanced Pointer Parameter Test END----------------" ); |
|
128 } |
|
129 else if (aGroupId == LONG_TRACE_TEST) |
|
130 { |
|
131 // Print out n times traces those lengths are 60, 300, 512 and 600 characters. |
|
132 // Print out also some traces those parameter total length is more than 512 |
|
133 Kern::Printf( "--------------TraceCompilerTesterAdvanced Long Trace Test START----------------" ); |
|
134 |
|
135 TInt i=0; |
|
136 TUint numberOfTraces = 1; |
|
137 TInt32 freq = NKern::FastCounterFrequency(); |
|
138 TUint32 startTime; |
|
139 TUint32 endTime; |
|
140 TUint32 time; |
|
141 |
|
142 TUint timeTestNumber1 = 0; |
|
143 TUint timeTestNumber2 = 0; |
|
144 TUint timeTestNumber3 = 0; |
|
145 TUint timeTestNumber4 = 0; |
|
146 TUint timeTestNumber5 = 0; |
|
147 TUint timeTestNumber6 = 0; |
|
148 TUint timeTestNumber7 = 0; |
|
149 // ---------------------------- Ascii60 ---------------------------- |
|
150 startTime = NKern::FastCounter(); |
|
151 Kern::Printf( "--------------TraceCompilerTesterAdvanced Long Trace Test : Ascii60----------------" ); |
|
152 for (i=0; i < numberOfTraces; i++) |
|
153 { |
|
154 OstTraceExt1( LONG_TRACE_TEST, ASCII60, "Ascii60: %s", buf60); |
|
155 } |
|
156 endTime = NKern::FastCounter(); |
|
157 time = (endTime - startTime) * 1000 / freq; |
|
158 |
|
159 timeTestNumber1 = time; |
|
160 // ---------------------------- Ascii60 ---------------------------- |
|
161 |
|
162 // ---------------------------- Ascii300 ---------------------------- |
|
163 startTime = NKern::FastCounter(); |
|
164 Kern::Printf( "--------------TraceCompilerTesterAdvanced Long Trace Test : Ascii300----------------" ); |
|
165 for (i=0; i < numberOfTraces; i++) |
|
166 { |
|
167 OstTraceExt1( LONG_TRACE_TEST, ASCII300, "Ascii300: %s", buf300); |
|
168 } |
|
169 endTime = NKern::FastCounter(); |
|
170 time = (endTime - startTime) * 1000 / freq; |
|
171 |
|
172 timeTestNumber2 = time; |
|
173 // ---------------------------- Ascii300 ---------------------------- |
|
174 |
|
175 // ---------------------------- Ascii512 ---------------------------- |
|
176 startTime = NKern::FastCounter(); |
|
177 Kern::Printf( "--------------TraceCompilerTesterAdvanced Long Trace Test : Ascii512----------------" ); |
|
178 for (i=0; i < numberOfTraces; i++) |
|
179 { |
|
180 OstTraceExt1( LONG_TRACE_TEST, ASCII512, "Ascii512: %s", buf512); |
|
181 } |
|
182 endTime = NKern::FastCounter(); |
|
183 time = (endTime - startTime) * 1000 / freq; |
|
184 |
|
185 timeTestNumber3 = time; |
|
186 // ---------------------------- Ascii512 ---------------------------- |
|
187 |
|
188 // ---------------------------- Ascii600 ---------------------------- |
|
189 startTime = NKern::FastCounter(); |
|
190 Kern::Printf( "--------------TraceCompilerTesterAdvanced Long Trace Test : Ascii600----------------" ); |
|
191 for (i=0; i < numberOfTraces; i++) |
|
192 { |
|
193 OstTraceExt1( LONG_TRACE_TEST, ASCII600, "Ascii600: %s", buf600); |
|
194 } |
|
195 endTime = NKern::FastCounter(); |
|
196 time = (endTime - startTime) * 1000 / freq; |
|
197 |
|
198 timeTestNumber4 = time; |
|
199 // ---------------------------- Ascii600 ---------------------------- |
|
200 |
|
201 // ---------------------------- Ascii300 + Ascii512 ---------------------------- |
|
202 startTime = NKern::FastCounter(); |
|
203 Kern::Printf( "--------------TraceCompilerTesterAdvanced Long Trace Test : Ascii300 + Ascii512----------------" ); |
|
204 for (i=0; i < numberOfTraces; i++) |
|
205 { |
|
206 OstTraceExt2( LONG_TRACE_TEST, ASCII300_ASCII512, "Ascii300: %s Ascii512: %s", buf300, buf512); |
|
207 } |
|
208 endTime = NKern::FastCounter(); |
|
209 time = (endTime - startTime) * 1000 / freq; |
|
210 |
|
211 timeTestNumber5 = time; |
|
212 // ---------------------------- Ascii300 + Ascii512 ---------------------------- |
|
213 |
|
214 // ---------------------------- Ascii600 + Ascii300 ---------------------------- |
|
215 startTime = NKern::FastCounter(); |
|
216 Kern::Printf( "--------------TraceCompilerTesterAdvanced Long Trace Test : Ascii600 + Ascii300----------------" ); |
|
217 for (i=0; i < numberOfTraces; i++) |
|
218 { |
|
219 OstTraceExt2( LONG_TRACE_TEST, ASCII600_ASCII300, "Ascii600: %s Ascii300: %s", buf600, buf300); |
|
220 } |
|
221 endTime = NKern::FastCounter(); |
|
222 time = (endTime - startTime) * 1000 / freq; |
|
223 |
|
224 timeTestNumber6 = time; |
|
225 // ---------------------------- Ascii600 + Ascii300 ---------------------------- |
|
226 |
|
227 // ---------------------------- Ascii333 + Ascii333 ---------------------------- |
|
228 startTime = NKern::FastCounter(); |
|
229 Kern::Printf( "--------------TraceCompilerTesterAdvanced Long Trace Test : Ascii333 + Ascii333----------------" ); |
|
230 for (i=0; i < numberOfTraces; i++) |
|
231 { |
|
232 OstTraceExt2( LONG_TRACE_TEST, ASCII333_ASCII333, "Ascii333: %s Ascii333: %s", buf333, buf333); |
|
233 } |
|
234 endTime = NKern::FastCounter(); |
|
235 time = (endTime - startTime) * 1000 / freq; |
|
236 |
|
237 timeTestNumber7 = time; |
|
238 // ---------------------------- Ascii333 + Ascii333 ---------------------------- |
|
239 |
|
240 Kern::Printf( "--------------TraceCompilerTesterAdvanced----------------" ); |
|
241 Kern::Printf( "Ascii60: %d", timeTestNumber1 ); |
|
242 Kern::Printf( "Ascii300: %d", timeTestNumber2 ); |
|
243 Kern::Printf( "Ascii512: %d", timeTestNumber3 ); |
|
244 Kern::Printf( "Ascii600: %d", timeTestNumber4 ); |
|
245 Kern::Printf( "Ascii300 + Ascii512: %d", timeTestNumber5 ); |
|
246 Kern::Printf( "Ascii600 + Ascii300: %d", timeTestNumber6 ); |
|
247 Kern::Printf( "Ascii333 + Ascii333: %d", timeTestNumber7 ); |
|
248 Kern::Printf( "--------------TraceCompilerTesterAdvanced----------------" ); |
|
249 |
|
250 Kern::Printf( "--------------TraceCompilerTesterAdvanced Long Trace Test END----------------" ); |
|
251 } |
|
252 else if (aGroupId == SHORT_TRACE_TEST) |
|
253 { |
|
254 Kern::Printf( "--------------TraceCompilerTesterAdvanced Short Trace Test START----------------" ); |
|
255 Kern::Printf( "--------------TraceCompilerTesterAdvanced Short Trace Test : Ascii1----------------" ); |
|
256 OstTraceExt1( SHORT_TRACE_TEST, ASCII1, "Ascii1: %s", buf1); |
|
257 Kern::Printf( "--------------TraceCompilerTesterAdvanced Short Trace Test : Ascii2----------------" ); |
|
258 OstTraceExt1( SHORT_TRACE_TEST, ASCII2, "Ascii2: %s", buf2); |
|
259 Kern::Printf( "--------------TraceCompilerTesterAdvanced Short Trace Test : Ascii3----------------" ); |
|
260 OstTraceExt1( SHORT_TRACE_TEST, ASCII3, "Ascii3: %s", buf3); |
|
261 Kern::Printf( "--------------TraceCompilerTesterAdvanced Short Trace Test : Ascii4----------------" ); |
|
262 OstTraceExt1( SHORT_TRACE_TEST, ASCII4, "Ascii4: %s", buf4); |
|
263 Kern::Printf( "--------------TraceCompilerTesterAdvanced Short Trace Test : Ascii1 + Acii2----------------" ); |
|
264 OstTraceExt2( SHORT_TRACE_TEST, ASCII5, "Ascii1: %s Ascii2: %s", buf1, buf2); |
|
265 |
|
266 Kern::Printf( "--------------TraceCompilerTesterAdvanced Short Trace Test END----------------" ); |
|
267 } |
|
268 else if (aGroupId == INCLUDED_NON_SOURCE_FILE_TEST) |
|
269 { |
|
270 // Print out traces from included non-source file that is defined in trace.properties file |
|
271 Kern::Printf( "--------------TraceCompilerTesterAdvanced Included Non-Source File Test START----------------" ); |
|
272 |
|
273 this->HelloWorld(); |
|
274 this->HelloMoon(); |
|
275 |
|
276 TUint32 value3 = GetBigValue1000(); |
|
277 TUint32 value4 = GetBigValue2000(); |
|
278 |
|
279 Kern::Printf( "--------------TraceCompilerTesterAdvanced Included Non-Source File Test END----------------" ); |
|
280 |
|
281 } |
|
282 else if (aGroupId == TRACE_FLOW) |
|
283 { |
|
284 OstTrace0(TRACE_FLOW, TEST_TRACE_2, "Test OLD TraceCompiler"); |
|
285 // This test can also use to test function parameters |
|
286 Kern::Printf( "--------------TraceCompilerTesterAdvanced Common Source File Test START----------------"); |
|
287 DTraceCompilerTesterCommon1* common1 = new DTraceCompilerTesterCommon1(); |
|
288 TInt32 sum = common1->SumValues(-1, -2, 100, 200); |
|
289 delete common1; |
|
290 Kern::Printf( "--------------TraceCompilerTesterAdvanced Common Source File Test END----------------"); |
|
291 } |
|
292 else if (aGroupId == KEKKONEN) |
|
293 { |
|
294 Kern::Printf( "--------------TraceCompilerTesterAdvanced Kekkonen START----------------"); |
|
295 DTraceCompilerTesterCommon2* common2 = new DTraceCompilerTesterCommon2(); |
|
296 common2->Kekkonen(); |
|
297 delete common2; |
|
298 Kern::Printf( "--------------TraceCompilerTesterAdvanced Kekkonen END----------------"); |
|
299 } |
|
300 else if (aGroupId == TRACE_STATE) |
|
301 { |
|
302 Kern::Printf( "--------------TraceCompilerTesterAdvanced State Trace Test START----------------"); |
|
303 OstTraceState0(STATE_TRACE_0, "Kone1", "Running"); |
|
304 OstTraceState1(STATE_TRACE_1, "Kone2", "Stopped", this); |
|
305 Kern::Printf( "--------------TraceCompilerTesterAdvanced State Trace Test END----------------"); |
|
306 } |
|
307 else if (aGroupId == TRACE_DATA) |
|
308 { |
|
309 Kern::Printf( "--------------TraceCompilerTesterAdvanced Data Trace Test START----------------"); |
|
310 |
|
311 TBuf8<601> data(buf600); |
|
312 OstTraceData( TRACE_DATA, TRACE_DATA_TRACE, |
|
313 "DTraceCoreXtiIf::DebugPrintMsg - Msg via XTI IF 0x%{hex8[]}", data.Ptr(), data.Size() ); |
|
314 Kern::Printf( "--------------TraceCompilerTesterAdvanced Data Trace Test END----------------"); |
|
315 } |
|
316 else if (aGroupId == POST_CODE_TEST) |
|
317 { |
|
318 Kern::Printf( "--------------TraceCompilerTesterAdvanced POST Code Trace Test START----------------"); |
|
319 OstTrace0(POST_CODE_TEST, POST1, "Print some POST code traces"); |
|
320 Kern::Printf("[POST][X-Loader][Started][OK]"); |
|
321 Kern::Printf("[POST][BootUp][Reset reason][PowerOn]"); |
|
322 Kern::NanoWait(50000000); |
|
323 Kern::Printf("[POST][X-Loader][Authenticate][OK]"); |
|
324 Kern::NanoWait(100000000); |
|
325 Kern::Printf("[POST][X-Loader][load][OK]"); |
|
326 Kern::NanoWait(100000000); |
|
327 Kern::Printf("[POST][X-Loader][Authenticate][OK]"); |
|
328 Kern::NanoWait(700000000); |
|
329 Kern::Printf("[POST][X-Loader][load][OK]"); |
|
330 Kern::NanoWait(50000000); |
|
331 Kern::Printf("[POST][X-Loader][load][OK]"); |
|
332 Kern::NanoWait(50000000); |
|
333 Kern::Printf("[POST][X-Loader][load][OK]"); |
|
334 Kern::NanoWait(50000000); |
|
335 Kern::Printf("[POST][X-Loader][Authenticate][OK]"); |
|
336 Kern::NanoWait(200000000); |
|
337 Kern::Printf("[POST][Boot strap][Started][OK]"); |
|
338 Kern::NanoWait(10000000); |
|
339 Kern::Printf("[POST][Estart][started][OK]"); |
|
340 Kern::NanoWait(10000000); |
|
341 Kern::Printf("[POST][Estart][CompositeFileSys.][OK]"); |
|
342 Kern::NanoWait(500000000); |
|
343 Kern::Printf("[POST][Mount][Drive][OK]"); |
|
344 Kern::NanoWait(200000000); |
|
345 Kern::Printf("[POST][Mount][Drive][OK]"); |
|
346 Kern::NanoWait(200000000); |
|
347 Kern::Printf("[POST][Estart][ISC API start][OK]"); |
|
348 Kern::NanoWait(300000000); |
|
349 Kern::Printf("[POST][Estart][userdisk format][No]"); |
|
350 Kern::NanoWait(10000000); |
|
351 Kern::Printf("[POST][Estart][secenv start][OK]"); |
|
352 Kern::NanoWait(20000000); |
|
353 Kern::Printf("[POST][Estart][startup mode][Local]"); |
|
354 Kern::NanoWait(10000000); |
|
355 Kern::Printf("[POST][Estart][Language selection][OK]"); |
|
356 Kern::NanoWait(200000000); |
|
357 Kern::Printf("[POST][SelfTest][Started][FAIL][KErrOutOfMemory]"); |
|
358 Kern::NanoWait(200000000); |
|
359 Kern::Printf("[POST][BT][Started][OK]"); |
|
360 Kern::NanoWait(800000000); |
|
361 Kern::Printf("[POST][WLAN][Started][OK]"); |
|
362 Kern::NanoWait(800000000); |
|
363 Kern::Printf("[POST][Display][Started][OK]"); |
|
364 Kern::NanoWait(800000000); |
|
365 Kern::Printf("[POST][Camera][Started][OK]"); |
|
366 Kern::NanoWait(80000000); |
|
367 Kern::Printf("[POST][mc_kernelagent][ExtensionInit0][OK]"); |
|
368 Kern::NanoWait(100000000); |
|
369 Kern::Printf("[POST][mc_sender][Pre-init][OK]"); |
|
370 Kern::NanoWait(100000000); |
|
371 Kern::Printf("[POST][mc_useragent][MobileCrashWriter init][OK]"); |
|
372 Kern::Printf( "--------------TraceCompilerTesterAdvanced POST Code Trace Test END----------------"); |
|
373 } |
|
374 } |
|
375 |
|
376 /** |
|
377 * Callback function for Trace Deactivation |
|
378 * |
|
379 * @param aComponentId |
|
380 * @param aGroupId |
|
381 */ |
|
382 void DTraceCompilerTesterAdvanced::TraceDeactivated( TUint32 aComponentId, TUint16 aGroupId ) |
|
383 { |
|
384 Kern::Printf( "DTraceCompilerTesterAdvanced::TraceDeactivated - ComponentId = 0x%x, GroupId = 0x%x", aComponentId, aGroupId ); |
|
385 } |
|
386 |
|
387 |
|
388 /** |
|
389 * The entry point for a standard extension. Creates Long Trace Tester extension. |
|
390 * |
|
391 * @return KErrNone, if successful |
|
392 */ |
|
393 DECLARE_STANDARD_EXTENSION() //lint !e960 !e1717 ¤/#((& Symbian |
|
394 { |
|
395 |
|
396 TInt ret( KErrNone ); |
|
397 |
|
398 DTraceCompilerTesterAdvanced* longTraceTester = new DTraceCompilerTesterAdvanced(); |
|
399 |
|
400 if( longTraceTester == NULL ) |
|
401 { |
|
402 ret = KErrNoMemory; |
|
403 } |
|
404 |
|
405 if ( ret == KErrNone ) |
|
406 { |
|
407 // construct instance |
|
408 ret = longTraceTester->Construct(); |
|
409 } |
|
410 |
|
411 return ret; |
|
412 } |
|
413 // End of File |