xref: /aosp_15_r20/external/intel-media-driver/media_driver/agnostic/common/cm/cm_printf_host.cpp (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
1 /*
2 * Copyright (c) 2017, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file      cm_printf_host.cpp
24 //! \brief     Contains Class PFParser definitions
25 //!
26 
27 #include "cm_printf_host.h"
28 
29 #if CM_KERNEL_PRINTF_ON
30 
31 #include "cm_debug.h"
32 
getToken(void)33 void PFParser::getToken(void)
34 {
35     mPrevToken = mCurrToken;
36     mCurrToken = Token();
37 
38     // This is a lexer that has 2 modes
39     // Inside a conversion specification and outside
40     while (*mCurrLoc != '\0')
41     {
42         if (!mInSpec)
43         {
44             // We're just picking off characters until we see a %
45             mCurrToken.mTokenType = Token::String;
46 
47             while (*mCurrLoc != '\0')
48             {
49                 if (*mCurrLoc == '%')
50                 {
51                     // Peek to check for %%
52                     if (*(mCurrLoc+1) != '\0' && *(mCurrLoc+1) != '%')
53                     {
54                         // This is definitely a directive, not a %%
55                         break;
56                     }
57                     // This IS %% so take another character off the input
58                     mCurrToken.mTokenString += *mCurrLoc++;
59                 }
60                 mCurrToken.mTokenString += *mCurrLoc++;
61             }
62 
63             if (*mCurrLoc == '%')
64                 mInSpec = true;
65 
66             if (mCurrToken.mTokenString.length() > 0)
67                 return;
68         }
69 
70         if (mInSpec)
71         {
72             char currChar = *mCurrLoc++;
73             switch(currChar)
74             {
75             default:
76                 // We've had an unexpected character
77                 mCurrToken.mTokenType = Token::Error;
78                 mCurrToken.mTokenString += currChar; // Preserve the error char
79                 mInSpec = false; // End of the format spec
80                 return;
81             case '%':
82                 mCurrToken.mTokenType = Token::Percent;
83                 return;
84             case '-':
85                 mCurrToken.mTokenType = Token::Minus;
86                 return;
87             case '+':
88                 mCurrToken.mTokenType = Token::Plus;
89                 return;
90             case ' ':
91                 mCurrToken.mTokenType = Token::Space;
92                 return;
93             case '.':
94                 mCurrToken.mTokenType = Token::Period;
95                 return;
96             case '#':
97                 mCurrToken.mTokenType = Token::Hash;
98                 return;
99             case '*':
100                 mCurrToken.mTokenType = Token::Star;
101                 return;
102             case 'h':
103                 // Have to deal with 'hh'
104                 if (*mCurrLoc == 'h')
105                 {
106                     mCurrLoc++;
107                     mCurrToken.mTokenType = Token::hh_Mod;
108                     return;
109                 }
110                 mCurrToken.mTokenType = Token::h_Mod;
111                 return;
112             case 'l':
113                 // Have to deal with 'll'
114                 if (*mCurrLoc == 'l')
115                 {
116                     mCurrLoc++;
117                     mCurrToken.mTokenType = Token::ll_Mod;
118                     return;
119                 }
120                 mCurrToken.mTokenType = Token::l_Mod;
121                 return;
122             case 'j':
123                 mCurrToken.mTokenType = Token::j_Mod;
124                 return;
125             case 'z':
126                 mCurrToken.mTokenType = Token::z_Mod;
127                 return;
128             case 't':
129                 mCurrToken.mTokenType = Token::t_Mod;
130                 return;
131             case 'L':
132                 mCurrToken.mTokenType = Token::L_Mod;
133                 return;
134             case 'c':
135                 mCurrToken.mTokenType = Token::c_Conv;
136                 mInSpec = false; // End of the format spec
137                 return;
138             case 's':
139                 mCurrToken.mTokenType = Token::s_Conv;
140                 mInSpec = false; // End of the format spec
141                 return;
142             case 'd':
143                 mCurrToken.mTokenType = Token::d_Conv;
144                 mInSpec = false; // End of the format spec
145                 return;
146             case 'i':
147                 mCurrToken.mTokenType = Token::i_Conv;
148                 mInSpec = false; // End of the format spec
149                 return;
150             case 'o':
151                 mCurrToken.mTokenType = Token::o_Conv;
152                 mInSpec = false; // End of the format spec
153                 return;
154             case 'x':
155                 mCurrToken.mTokenType = Token::x_Conv;
156                 mInSpec = false; // End of the format spec
157                 return;
158             case 'X':
159                 mCurrToken.mTokenType = Token::X_Conv;
160                 mInSpec = false; // End of the format spec
161                 return;
162             case 'u':
163                 mCurrToken.mTokenType = Token::u_Conv;
164                 mInSpec = false; // End of the format spec
165                 return;
166             case 'f':
167                 mCurrToken.mTokenType = Token::f_Conv;
168                 mInSpec = false; // End of the format spec
169                 return;
170             case 'F':
171                 mCurrToken.mTokenType = Token::F_Conv;
172                 mInSpec = false; // End of the format spec
173                 return;
174             case 'e':
175                 mCurrToken.mTokenType = Token::e_Conv;
176                 mInSpec = false; // End of the format spec
177                 return;
178             case 'E':
179                 mCurrToken.mTokenType = Token::E_Conv;
180                 mInSpec = false; // End of the format spec
181                 return;
182             case 'a':
183                 mCurrToken.mTokenType = Token::a_Conv;
184                 mInSpec = false; // End of the format spec
185                 return;
186             case 'A':
187                 mCurrToken.mTokenType = Token::A_Conv;
188                 mInSpec = false; // End of the format spec
189                 return;
190             case 'g':
191                 mCurrToken.mTokenType = Token::g_Conv;
192                 mInSpec = false; // End of the format spec
193                 return;
194             case 'G':
195                 mCurrToken.mTokenType = Token::G_Conv;
196                 mInSpec = false; // End of the format spec
197                 return;
198             case 'n':
199                 mCurrToken.mTokenType = Token::n_Conv;
200                 mInSpec = false; // End of the format spec
201                 return;
202             case 'p':
203                 mCurrToken.mTokenType = Token::p_Conv;
204                 mInSpec = false; // End of the format spec
205                 return;
206             case '0':
207                 if (*mCurrLoc < '1' || *mCurrLoc > '9')
208                 {
209                     // Next character not part of a larger integer
210                     mCurrToken.mTokenType = Token::Zero;
211                     return;
212                 }
213                 // Deliberately drop through
214             case '1':
215             case '2':
216             case '3':
217             case '4':
218             case '5':
219             case '6':
220             case '7':
221             case '8':
222             case '9':
223                 mCurrToken.mTokenString += currChar;
224                 while (*mCurrLoc >= '0' && *mCurrLoc <= '9')
225                 {
226                     mCurrToken.mTokenString += *mCurrLoc++;
227                 }
228                 // Create integer
229                 // Since we've created this integer string and we know it is simple we can use
230                 // atoi knowing that it won't throw an error
231                 mCurrToken.mTokenInt = atoi(mCurrToken.mTokenString.c_str());
232                 mCurrToken.mTokenType = Token::Integer;
233                 return;
234             }
235         }
236     }
237 
238     mCurrToken.mTokenType = Token::End;
239 }
240 
accept(PFParser::Token::TokenType s)241 bool PFParser::accept(PFParser::Token::TokenType s)
242 {
243     if (mCurrToken == s)
244     {
245         getToken();
246         return true;
247     }
248     return false;
249 }
250 
expect(Token::TokenType s)251 bool PFParser::expect(Token::TokenType s)
252 {
253     if (accept(s))
254         return true;
255     error();
256     return false;
257 }
258 
format(void)259 int PFParser::format(void)
260 {
261     if (mCurrToken == Token::_None_)
262     {
263         getToken();
264     }
265     while(mCurrToken != Token::End && mCurrToken != Token::Error)
266     {
267         if (accept(Token::String))
268         {
269         }
270         else if (accept(Token::Percent))
271         {
272             return directive();
273         }
274     }
275     return 0;
276 }
277 
directive(void)278 int PFParser::directive(void)
279 {
280     int numArgs = 0;
281     flags();
282     numArgs += width();
283     numArgs += precision();
284     length_modifier();
285 
286     int numConvArgs = conversion();
287     if (numConvArgs == 0)
288     {
289         // Not expecting ANY arguments
290         // Ignore any previous directives (width, precision etc.)
291         numArgs = 0;
292     }
293     else
294     {
295         numArgs += numConvArgs;
296     }
297 
298     return numArgs;
299 }
300 
flags(void)301 void PFParser::flags(void)
302 {
303     if (accept(Token::Minus))
304     {
305     }
306 
307     if (accept(Token::Plus))
308     {
309     }
310 
311     if (accept(Token::Space))
312     {
313     }
314 
315     if (accept(Token::Zero))
316     {
317     }
318 
319     if (accept(Token::Hash))
320     {
321     }
322 }
323 
width(void)324 int PFParser::width(void)
325 {
326     if (accept(Token::Integer))
327     {
328         return 0;
329     }
330     else if (accept(Token::Star))
331     {
332         return 1;
333     }
334     return 0;
335 }
336 
precision(void)337 int PFParser::precision(void)
338 {
339     if (accept(Token::Period))
340     {
341         if (accept(Token::Integer))
342         {
343             return 0;
344         }
345         else if (expect(Token::Star))
346         {
347             return 1;
348         }
349         return 0;
350     }
351     return 0;
352 }
353 
length_modifier(void)354 void PFParser::length_modifier(void)
355 {
356     if (accept(Token::hh_Mod))
357     {
358     }
359     else if (accept(Token::h_Mod))
360     {
361     }
362     else if (accept(Token::l_Mod))
363     {
364     }
365     else if (accept(Token::ll_Mod))
366     {
367     }
368     else if (accept(Token::j_Mod))
369     {
370         mUnsupported = true;
371     }
372     else if (accept(Token::t_Mod))
373     {
374         mUnsupported = true;
375     }
376     else if (accept(Token::z_Mod))
377     {
378         mUnsupported = true;
379     }
380     else if (accept(Token::L_Mod))
381     {
382     }
383 }
384 
conversion(void)385 int PFParser::conversion(void)
386 {
387     int numArgs = 1;
388     if (accept(Token::Percent))
389     {
390         numArgs = 0;
391     }
392     else if (accept(Token::c_Conv))
393     {
394     }
395     else if (accept(Token::s_Conv))
396     {
397     }
398     else if (accept(Token::d_Conv))
399     {
400     }
401     else if (accept(Token::i_Conv))
402     {
403     }
404     else if (accept(Token::o_Conv))
405     {
406     }
407     else if (accept(Token::x_Conv))
408     {
409     }
410     else if (accept(Token::X_Conv))
411     {
412     }
413     else if (accept(Token::u_Conv))
414     {
415     }
416     else if (accept(Token::f_Conv))
417     {
418     }
419     else if (accept(Token::F_Conv))
420     {
421     }
422     else if (accept(Token::e_Conv))
423     {
424     }
425     else if (accept(Token::E_Conv))
426     {
427     }
428     else if (accept(Token::a_Conv))
429     {
430     }
431     else if (accept(Token::A_Conv))
432     {
433     }
434     else if (accept(Token::g_Conv))
435     {
436     }
437     else if (accept(Token::G_Conv))
438     {
439     }
440     else if (accept(Token::n_Conv))
441     {
442         mUnsupported = true;
443     }
444     else if (expect(Token::p_Conv))
445     {
446     }
447     else
448     {
449         // Expect must have failed
450         numArgs = 0;
451     }
452     return numArgs;
453 }
454 
CalcSizeFromHeader(unsigned char * memory)455 int CalcSizeFromHeader(unsigned char * memory)
456 {
457     PCM_PRINT_HEADER header = (PCM_PRINT_HEADER)memory;
458 
459     if((header->objectType == CM_PRINT_OBJECT_TYPE_MATRIX) ||
460        (header->objectType == CM_PRINT_OBJECT_TYPE_VECTOR))
461     {
462         switch (header->dataType)
463         {
464             case CM_PRINT_DATA_TYPE_CHAR   :
465                 return CM_PRINT_SIZE_WITH_PAYLOAD(header->height*header->width*sizeof(char           ));
466 
467             case CM_PRINT_DATA_TYPE_UCHAR  :
468                 return CM_PRINT_SIZE_WITH_PAYLOAD(header->height*header->width*sizeof(unsigned char  ));
469 
470             case CM_PRINT_DATA_TYPE_INT    :
471                 return CM_PRINT_SIZE_WITH_PAYLOAD(header->height*header->width*sizeof(int            ));
472 
473             case CM_PRINT_DATA_TYPE_UINT   :
474                 return CM_PRINT_SIZE_WITH_PAYLOAD(header->height*header->width*sizeof(unsigned int   ));
475 
476             case CM_PRINT_DATA_TYPE_FLOAT  :
477                 return CM_PRINT_SIZE_WITH_PAYLOAD(header->height*header->width*sizeof(float          ));
478 
479             case CM_PRINT_DATA_TYPE_SHORT  :
480                 return CM_PRINT_SIZE_WITH_PAYLOAD(header->height*header->width*sizeof(short          ));
481 
482             case CM_PRINT_DATA_TYPE_USHORT :
483                 return CM_PRINT_SIZE_WITH_PAYLOAD(header->height*header->width*sizeof(unsigned short ));
484 
485             case CM_PRINT_DATA_TYPE_QWORD  :
486                 return CM_PRINT_SIZE_WITH_PAYLOAD(header->height*header->width*sizeof(long long      ));
487 
488             case CM_PRINT_DATA_TYPE_UQWORD :
489                 return CM_PRINT_SIZE_WITH_PAYLOAD(header->height*header->width*sizeof(unsigned long long ));
490 
491             case CM_PRINT_DATA_TYPE_DOUBLE :
492                 return CM_PRINT_SIZE_WITH_PAYLOAD(header->height*header->width*sizeof(double         ));
493 
494             default:
495                 CM_ASSERTMESSAGE("Error: Invalid print data type.");
496         }
497         return PRINT_HEADER_SIZE;
498     }
499     else if(header->objectType == CM_PRINT_OBJECT_TYPE_STRING ||
500             header->objectType == CM_PRINT_OBJECT_TYPE_FORMAT)
501     {
502         return PRINT_HEADER_SIZE + PRINT_FORMAT_STRING_SIZE;
503     }
504     else if(header->objectType == CM_PRINT_OBJECT_TYPE_SCALAR)
505     {
506         if(!((header->dataType == CM_PRINT_DATA_TYPE_CHAR)   ||
507              (header->dataType == CM_PRINT_DATA_TYPE_UCHAR)  ||
508              (header->dataType == CM_PRINT_DATA_TYPE_UINT)   ||
509              (header->dataType == CM_PRINT_DATA_TYPE_INT)    ||
510              (header->dataType == CM_PRINT_DATA_TYPE_USHORT) ||
511              (header->dataType == CM_PRINT_DATA_TYPE_SHORT)  ||
512              (header->dataType == CM_PRINT_DATA_TYPE_DOUBLE) ||
513              (header->dataType == CM_PRINT_DATA_TYPE_QWORD)  ||
514              (header->dataType == CM_PRINT_DATA_TYPE_UQWORD) ||
515              (header->dataType == CM_PRINT_DATA_TYPE_FLOAT)))
516         {
517             CM_ASSERTMESSAGE("Error: Invalid print data type.");
518         }
519         return PRINT_HEADER_SIZE;
520     }
521     else
522     {
523         CM_ASSERTMESSAGE("Error: Invalid print object type.");
524         return PRINT_HEADER_SIZE;
525     }
526 }
527 
flush(void)528 void PFParser::flush(void)
529 {
530     if (mInputStart && mCurrLoc)
531     {
532         if (mCurrToken != Token::End &&
533             mCurrToken != Token::_None_)
534         {
535             // Tidy up any remaining characters
536             // Any characters that remain to be flushed need to be check for illegal directives (e.g. %n
537             // will cause an exception if attempted to be printed with no argument)
538             int numArgs = format();
539             if (mUnsupported)
540             {
541                 CM_PRINTF(mStreamOut,"Unsupported (but valid C++11) format string used : %s", mInputStart);
542                 reset();
543             }
544             else if (mError)
545             {
546                 CM_PRINTF(mStreamOut,"Error in printf format string : %s", mInputStart);
547                 reset();
548             }
549             else if (numArgs > 0)
550             {
551                 // Not enough arguments provided for remaining directives
552                 CM_PRINTF(mStreamOut,"Not enough (no) arguments supplied for format string : %s", mInputStart);
553                 reset();
554             }
555             else
556             {
557                 CM_PRINTF(mStreamOut,"%s", mInputStart);
558             }
559         }
560         reset();
561     }
562 }
563 
GetNextFmtToken(char * tkn,size_t size)564 PRINT_FMT_STATUS PFParser::GetNextFmtToken(char* tkn, size_t size)
565 {
566     memset(tkn, 0, size);
567 
568     if (mNumMultArg)
569     {
570         if (!mArgsExpected)
571         {
572             // Copy the whole of the format string into the token
573             if ((size_t)(mCurrLoc - mInputStart) <= size)
574             {
575                 memcpy(tkn, mInputStart, mCurrLoc - mInputStart);
576                 tkn[mCurrLoc - mInputStart] = '\0';
577                 return PF_SUCCESS;
578             }
579             return PF_FAIL;
580         }
581         // Still processing input arguments
582         return PF_SUCCESS;
583     }
584 
585     int numArgs = format();
586     switch (numArgs)
587     {
588     default:
589         return PF_FAIL; // Something has gone wrong
590     case 0:
591     case 1:
592         // Copy the whole of the format string into the token
593         if ((size_t)(mCurrLoc - mInputStart) <= size)
594         {
595             memcpy(tkn, mInputStart, mCurrLoc - mInputStart);
596             tkn[mCurrLoc - mInputStart] = '\0';
597             return PF_SUCCESS;
598         }
599         return PF_FAIL;
600     case 2:
601     case 3:
602         mNumMultArg = numArgs - 1;
603         mArgsExpected = numArgs - 1;
604         return PF_SUCCESS;
605     }
606 }
607 
outputToken(const char * tkn,PCM_PRINT_HEADER header)608 bool PFParser::outputToken(const char *tkn, PCM_PRINT_HEADER header)
609 {
610     if (mNumMultArg && mArgsExpected)
611     {
612         // Processing items for multi-arg directives
613         if (header->objectType == CM_PRINT_OBJECT_TYPE_SCALAR &&
614             header->dataType != CM_PRINT_DATA_TYPE_FLOAT &&
615             header->dataType != CM_PRINT_DATA_TYPE_DOUBLE &&
616             header->dataType != CM_PRINT_DATA_TYPE_QWORD &&
617             header->dataType != CM_PRINT_DATA_TYPE_UQWORD)
618         {
619             // Received an int type argument as expected
620             switch (header->dataType)
621             {
622                 case CM_PRINT_DATA_TYPE_INT    :
623                     mArgs[mNumMultArg - mArgsExpected] = *((int*            )&(header->scalar64));
624                     break;
625                 case CM_PRINT_DATA_TYPE_UINT   :
626                     mArgs[mNumMultArg - mArgsExpected] = *((unsigned int*   )&(header->scalar64));
627                     break;
628                 case CM_PRINT_DATA_TYPE_CHAR   :
629                     mArgs[mNumMultArg - mArgsExpected] = *((char*           )&(header->scalar64));
630                     break;
631                 case CM_PRINT_DATA_TYPE_UCHAR  :
632                     mArgs[mNumMultArg - mArgsExpected] = *((unsigned char*  )&(header->scalar64));
633                     break;
634                 case CM_PRINT_DATA_TYPE_SHORT  :
635                     mArgs[mNumMultArg - mArgsExpected] = *((short*         )&(header->scalar64));
636                     break;
637                 case CM_PRINT_DATA_TYPE_USHORT :
638                     mArgs[mNumMultArg - mArgsExpected] = *((unsigned short*)&(header->scalar64));
639                     break;
640             }
641             mArgsExpected -= 1;
642             return true;
643         }
644         else
645         {
646             // Not received the expected argument
647             // Dump what is in the format string and attempt to recover as well as possible
648             return false;
649         }
650     }
651 
652     // Inform the user that they've used an unsupported format string if that is the case
653     // (e.g. %jd, %td etc.)
654     if (mUnsupported)
655     {
656         CM_PRINTF(mStreamOut,"Unsupported (but valid C++11) printf format string : %s", tkn);
657         reset();
658         return true;
659     }
660     // Inform the user that they've got an error (illegal format string)
661     if (mError)
662     {
663         CM_PRINTF(mStreamOut, "Error in printf format string : %s", tkn);
664         reset();
665         return true;
666     }
667 
668     // Output as appropriate
669     if (!mNumMultArg)
670     {
671         switch (header->dataType)
672         {
673         case CM_PRINT_DATA_TYPE_INT    :
674             CM_PRINTF(mStreamOut, tkn, *((int*)&(header->scalar64)));
675             break;
676 
677         case CM_PRINT_DATA_TYPE_UINT   :
678             CM_PRINTF(mStreamOut, tkn, *((unsigned int*)&(header->scalar64)));
679             break;
680 
681         case CM_PRINT_DATA_TYPE_CHAR   :
682             CM_PRINTF(mStreamOut, tkn, *((char*)&(header->scalar64)));
683             break;
684 
685         case CM_PRINT_DATA_TYPE_UCHAR  :
686             CM_PRINTF(mStreamOut, tkn, *((unsigned char*)&(header->scalar64)));
687             break;
688 
689         case CM_PRINT_DATA_TYPE_FLOAT  :
690             CM_PRINTF(mStreamOut, tkn, *((float*)&(header->scalar64)));
691             break;
692 
693         case CM_PRINT_DATA_TYPE_SHORT  :
694             CM_PRINTF(mStreamOut, tkn, *((short*)&(header->scalar64)));
695             break;
696 
697         case CM_PRINT_DATA_TYPE_USHORT :
698             CM_PRINTF(mStreamOut, tkn, *((unsigned short*)&(header->scalar64)));
699             break;
700 
701         case CM_PRINT_DATA_TYPE_DOUBLE :
702             CM_PRINTF(mStreamOut, tkn, *((double*)&(header->scalar64)));
703             break;
704 
705         case CM_PRINT_DATA_TYPE_QWORD  :
706             CM_PRINTF(mStreamOut, tkn, *((long long*)&(header->scalar64)));
707             break;
708 
709         case CM_PRINT_DATA_TYPE_UQWORD :
710             CM_PRINTF(mStreamOut, tkn, *((unsigned long long*)&(header->scalar64)));
711             break;
712         }
713     }
714     else if (mNumMultArg == 1)
715     {
716         switch (header->dataType)
717         {
718         case CM_PRINT_DATA_TYPE_INT    :
719             CM_PRINTF(mStreamOut,tkn, mArgs[0], *((int*            )&(header->scalar64)));
720             break;
721 
722         case CM_PRINT_DATA_TYPE_UINT   :
723             CM_PRINTF(mStreamOut,tkn, mArgs[0], *((unsigned int*   )&(header->scalar64)));
724             break;
725 
726         case CM_PRINT_DATA_TYPE_CHAR   :
727             CM_PRINTF(mStreamOut,tkn, mArgs[0], *((char*           )&(header->scalar64)));
728             break;
729 
730         case CM_PRINT_DATA_TYPE_UCHAR  :
731             CM_PRINTF(mStreamOut,tkn, mArgs[0], *((unsigned char*  )&(header->scalar64)));
732             break;
733 
734         case CM_PRINT_DATA_TYPE_FLOAT  :
735             CM_PRINTF(mStreamOut,tkn, mArgs[0], *((float*          )&(header->scalar64)));
736             break;
737 
738         case CM_PRINT_DATA_TYPE_SHORT  :
739             CM_PRINTF(mStreamOut,tkn, mArgs[0], *((short*          )&(header->scalar64)));
740             break;
741 
742         case CM_PRINT_DATA_TYPE_USHORT :
743             CM_PRINTF(mStreamOut,tkn, mArgs[0], *((unsigned short* )&(header->scalar64)));
744             break;
745 
746         case CM_PRINT_DATA_TYPE_DOUBLE :
747             CM_PRINTF(mStreamOut,tkn, mArgs[0], *((double*         )&(header->scalar64)));
748             break;
749 
750         case CM_PRINT_DATA_TYPE_QWORD  :
751             CM_PRINTF(mStreamOut,tkn, mArgs[0], *((long long*          )&(header->scalar64)));
752             break;
753 
754         case CM_PRINT_DATA_TYPE_UQWORD :
755             CM_PRINTF(mStreamOut,tkn, mArgs[0], *((unsigned long long* )&(header->scalar64)));
756             break;
757         }
758     }
759     else if (mNumMultArg == 2)
760     {
761         switch (header->dataType)
762         {
763         case CM_PRINT_DATA_TYPE_INT    :
764             CM_PRINTF(mStreamOut,tkn, mArgs[0], mArgs[1], *((int*            )&(header->scalar64)));
765             break;
766 
767         case CM_PRINT_DATA_TYPE_UINT   :
768             CM_PRINTF(mStreamOut,tkn, mArgs[0], mArgs[1], *((unsigned int*   )&(header->scalar64)));
769             break;
770 
771         case CM_PRINT_DATA_TYPE_CHAR   :
772             CM_PRINTF(mStreamOut,tkn, mArgs[0], mArgs[1], *((char*           )&(header->scalar64)));
773             break;
774 
775         case CM_PRINT_DATA_TYPE_UCHAR  :
776             CM_PRINTF(mStreamOut,tkn, mArgs[0], mArgs[1], *((unsigned char*  )&(header->scalar64)));
777             break;
778 
779         case CM_PRINT_DATA_TYPE_FLOAT  :
780             CM_PRINTF(mStreamOut,tkn, mArgs[0], mArgs[1], *((float*          )&(header->scalar64)));
781             break;
782 
783         case CM_PRINT_DATA_TYPE_SHORT  :
784             CM_PRINTF(mStreamOut,tkn, mArgs[0], mArgs[1], *((short*          )&(header->scalar64)));
785             break;
786 
787         case CM_PRINT_DATA_TYPE_USHORT :
788             CM_PRINTF(mStreamOut,tkn, mArgs[0], mArgs[1], *((unsigned short* )&(header->scalar64)));
789             break;
790 
791         case CM_PRINT_DATA_TYPE_DOUBLE :
792             CM_PRINTF(mStreamOut,tkn, mArgs[0], mArgs[1], *((double*         )&(header->scalar64)));
793             break;
794 
795         case CM_PRINT_DATA_TYPE_QWORD  :
796             CM_PRINTF(mStreamOut,tkn, mArgs[0], mArgs[1], *((long long*          )&(header->scalar64)));
797             break;
798 
799         case CM_PRINT_DATA_TYPE_UQWORD :
800             CM_PRINTF(mStreamOut,tkn, mArgs[0], mArgs[1], *((unsigned long long* )&(header->scalar64)));
801             break;
802         }
803     }
804 
805     reset();
806     return true;
807 }
DumpMemory(unsigned char * memory)808 void PFParser::DumpMemory(unsigned char * memory)
809 {
810     PCM_PRINT_HEADER header = (PCM_PRINT_HEADER)memory;
811     memory += PRINT_HEADER_SIZE;
812     int threadid = header->tid;
813 
814     if(!mNumMultArg && header->objectType == CM_PRINT_OBJECT_TYPE_MATRIX )
815     {
816         CM_PRINTF(mStreamOut,"\n Thread id %d, Matrix , Width %ud, Height %ud \n", threadid, header->width, header->height);
817     }
818     else if(!mNumMultArg && header->objectType == CM_PRINT_OBJECT_TYPE_VECTOR)
819     {
820         CM_PRINTF(mStreamOut, " \n Thread id %d, Vector , Width %ud\n", threadid, header->width);
821     }
822     else if(!mNumMultArg && header->objectType == CM_PRINT_OBJECT_TYPE_FORMAT)
823     {
824         // Flush any remaining characters from existing format string (if any)
825         flush();
826         setStart((char *)memory);
827     }
828     else if(!mNumMultArg && header->objectType == CM_PRINT_OBJECT_TYPE_STRING)
829     {
830         char tkn[PRINT_FORMAT_STRING_SIZE];
831         PRINT_FMT_STATUS status = GetNextFmtToken(tkn, PRINT_FORMAT_STRING_SIZE);
832         if (status == PF_SUCCESS)
833         {
834             // Inform the user that they've used an unsupported format string if that is the case
835             // (e.g. %jd, %td etc.)
836             if (mUnsupported)
837             {
838                 CM_PRINTF(mStreamOut, "Unsupported (but valid C++11) format string used : %s", tkn);
839             }
840             // Inform the user that they've got an error (illegal format string)
841             if (mError)
842             {
843                 CM_PRINTF(mStreamOut, "Error in printf format string : %s", tkn);
844             }
845 
846             if (mUnsupported || mError)
847             {
848                 reset();
849                 return;
850             }
851 
852             CM_PRINTF(mStreamOut, tkn, (char*)memory);
853             reset();
854         }
855 
856         return;
857     }
858     else if(header->objectType == CM_PRINT_OBJECT_TYPE_SCALAR)
859     {
860         char tkn[PRINT_FORMAT_STRING_SIZE];
861         PRINT_FMT_STATUS status = GetNextFmtToken(tkn, PRINT_FORMAT_STRING_SIZE);
862         if (status == PF_SUCCESS)
863         {
864             if (!outputToken(tkn, header))
865             {
866                 // Something has gone wrong
867                 // Reset multi-arg at least
868                 CM_PRINTF(mStreamOut, "Problem outputting with format string %s\n", tkn);
869                 mNumMultArg = mArgsExpected = 0;
870             }
871         }
872         return;
873     }
874     else
875     {
876         if (mNumMultArg)
877         {
878             // Something has gone wrong in multi-arg so reset
879             CM_PRINTF(mStreamOut, "Error in multi-arg directive\n");
880             mNumMultArg = 0;
881             mArgsExpected = 0;
882         }
883         else
884         {
885             CM_PRINTF(mStreamOut, "Unknown TYPE\n");
886         }
887         return;
888     }
889 }
890 
DumpAllThreadOutput(FILE * streamout,unsigned char * dumpMem,size_t buffersize)891 void DumpAllThreadOutput(FILE *streamout, unsigned char * dumpMem, size_t buffersize)
892 {
893     unsigned int off                =   PRINT_BUFFER_HEADER_SIZE;
894     PFParser     pState(streamout);
895 
896     while(1)
897     {
898         if((off + PRINT_HEADER_SIZE) >= buffersize)
899             break;
900 
901         if(off >= (*(unsigned int *)dumpMem))
902             break;
903 
904         unsigned int offsetFromHeader = CalcSizeFromHeader(dumpMem + off);
905         if( (off + offsetFromHeader) >= buffersize )
906             break;
907 
908         pState.DumpMemory(dumpMem + off);
909 
910         off += offsetFromHeader;
911     }
912 
913     // Flush any remaining characters in the format buffer
914     pState.flush();
915 
916 }
917 #endif
918