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