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