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