464 |
466 |
465 // ---------------------------------------------------------------------------- |
467 // ---------------------------------------------------------------------------- |
466 // CPPParser::HandleExports |
468 // CPPParser::HandleExports |
467 // ---------------------------------------------------------------------------- |
469 // ---------------------------------------------------------------------------- |
468 // |
470 // |
|
471 |
469 int CPPParser::HandleExports(string aFilename, string aVersion) |
472 int CPPParser::HandleExports(string aFilename, string aVersion) |
470 { |
473 { |
471 int ret = 0; |
474 int ret = 0; |
472 string ofilename = aFilename + ".2"; |
475 string ofilename = aFilename + ".2"; |
473 |
476 |
474 ifstream input(aFilename.c_str(), ios::in); |
477 ifstream input(aFilename.c_str(), ios::in); |
475 ofstream output(ofilename.c_str(), ios::out); |
478 ofstream output(ofilename.c_str(), ios::out); |
476 iOutputFilename = ofilename; |
479 iOutputFilename = ofilename; |
477 char c; |
480 char c; |
478 string toflush = ""; |
481 string toflush = ""; |
479 unsigned int matches = 0; |
482 string flush = ""; |
480 string tofind = STR_EXPORT_HACK; |
483 unsigned int matches = 0; |
481 string attribstr = STR_ATTRIBUTE_STR; |
484 string tofind = STR_EXPORT_HACK; |
482 string outputBuffer; |
485 string attribstr = STR_ATTRIBUTE_STR; |
483 outputBuffer.reserve(PREPROCESS_BUFFERSIZE); |
486 string outputBuffer; |
484 int state = EStateSearching; |
487 outputBuffer.reserve(PREPROCESS_BUFFERSIZE); |
485 bool purevirtual = false; |
488 int state = EStateSearching; |
486 bool possiblepurevirtual = false; |
489 char stackArray[MAX_ARRAY_COUNT] = {'\0'}; |
487 while (input.get(c)) |
490 int arryPos = 0; |
488 { |
491 |
489 if (outputBuffer.length() >= PREPROCESS_BUFFERSIZE) |
492 string isClass = "class"; |
490 { |
493 string isEnum = "enum"; |
491 output << outputBuffer; |
494 string isStruct = "struct"; |
492 outputBuffer = ""; |
495 string isUnion = "union"; |
493 } |
496 string isInline = "inline"; |
494 if (state == EStateSearching) |
497 |
495 { |
498 unsigned int clsPos = 0; |
496 if (c == tofind.at(matches)) |
499 unsigned int enmPos = 0; |
497 { |
500 unsigned int strctPos = 0; |
498 matches++; |
501 unsigned int inlinePos = 0; |
499 toflush += c; |
502 unsigned int unionPos = 0; |
500 } else |
503 char arraychar = '\0'; |
501 { |
504 |
502 matches = 0; |
505 unsigned int bufPos = 0; |
503 if (!toflush.empty()) |
506 |
504 { |
507 string temp; |
505 outputBuffer += toflush; |
508 string buf; |
506 toflush = ""; |
509 |
507 } |
510 bool possibleVirtualFunc = false; |
508 outputBuffer += c; |
511 bool virtualFunc = false; |
509 } |
512 bool ignorecheck = false; |
510 if (matches == tofind.length()) |
513 while (input.get(c)) |
511 { |
514 { |
512 toflush = ""; |
515 ignorecheck = false; |
513 state = EStateReplacing; |
516 if (outputBuffer.length() >= PREPROCESS_BUFFERSIZE) |
514 matches = 0; |
517 { |
515 } |
518 output << outputBuffer; |
516 } else if (state == EStateReplacing) |
519 outputBuffer = ""; |
517 { |
520 } |
518 if (c == '=') |
521 // Get the bufferpos |
519 { |
522 bufPos = (unsigned int)outputBuffer.length()-1; |
520 if (possiblepurevirtual == true && !toflush.empty()) |
523 |
521 { |
524 // delete buf (class\enum\struct) entry if next letter is not space |
522 outputBuffer += toflush; |
525 if ( buf.length() > 0 && state == EStateReplacing && (c != ' ' && c != '\t' && int(c) != 10)) |
523 toflush = ""; |
526 { |
524 } |
527 buf = ""; |
525 possiblepurevirtual = true; |
528 } |
526 toflush += c; |
529 if( c == isClass.at(clsPos)) |
527 } else if (possiblepurevirtual == true && c!= ';') |
530 { |
528 { |
531 if( clsPos == 0 ) // searching for class keyword with space before and after |
529 if (c == ' ') |
532 { |
530 { |
533 if(outputBuffer == "" || outputBuffer.at(bufPos) == ' ' || outputBuffer.at(bufPos) == '\t' |
531 toflush += c; |
534 || int(outputBuffer.at(bufPos)) == 10 || int(outputBuffer.at(bufPos)) == 32 ) |
532 } else if (c == '\t') |
535 clsPos++; |
533 { |
536 } |
534 toflush += c; |
537 else |
535 } else if (c == '0') |
538 clsPos++; |
536 { |
539 } |
537 toflush += c; |
540 |
538 purevirtual = true; |
541 else |
539 } else |
542 clsPos = 0; |
540 { |
543 if (clsPos == isClass.length()) // keyword found |
541 outputBuffer += toflush; |
544 { |
542 outputBuffer += c; |
545 clsPos = 0; |
543 toflush = ""; |
546 buf = isClass; |
544 possiblepurevirtual = false; |
547 ignorecheck = true; // in the current iteration don't match buf string with class\enum\struct keyword |
545 purevirtual = false; |
548 // as keyword may be part of some word like " classification" |
546 } |
549 } |
547 } else if (c == ';') |
550 |
548 { |
551 if( c == isUnion.at(unionPos)) |
549 state = EStateSearching; |
552 { |
550 if (purevirtual) |
553 if( unionPos == 0 ) // searching for union keyword with space before and after |
551 { |
554 { |
552 } else if (possiblepurevirtual) |
555 if(outputBuffer == "" || outputBuffer.at(bufPos) == ' ' || outputBuffer.at(bufPos) == '\t' |
553 { |
556 || int(outputBuffer.at(bufPos)) == 10 || int(outputBuffer.at(bufPos)) == 32 ) |
554 outputBuffer += toflush; |
557 unionPos++; |
555 toflush = ""; |
558 } |
556 } |
559 else |
557 |
560 unionPos++; |
558 outputBuffer += " "; |
561 } |
559 outputBuffer += attribstr; |
562 |
560 if (!toflush.empty()) |
563 else |
561 { |
564 unionPos = 0; |
562 outputBuffer += " "; |
565 if (unionPos == isUnion.length()) // keyword found |
563 outputBuffer += toflush; |
566 { |
564 toflush = ""; |
567 unionPos = 0; |
565 } |
568 buf = isUnion; |
566 possiblepurevirtual = false; |
569 ignorecheck = true; // in the current iteration don't match buf string with class\enum\struct\union keyword |
567 purevirtual = false; |
570 // as keyword may be part of some word like " classification" |
568 outputBuffer += ';'; |
571 } |
569 } else |
572 |
570 { |
573 if(c == isStruct.at(strctPos))// searching for struct keyword with space before and after |
571 outputBuffer += c; |
574 { |
572 } |
575 if( strctPos == 0 ) |
573 } else if (state == EStateReplaceDone) |
576 { |
574 { |
577 if(outputBuffer == "" || outputBuffer.at(bufPos) == ' ' || outputBuffer.at(bufPos) == '\t' |
575 |
578 || int(outputBuffer.at(bufPos)) == 10 ) |
576 } |
579 strctPos++; |
577 |
580 } |
578 } |
581 else |
579 if (outputBuffer.length() != 0) |
582 strctPos++; |
580 { |
583 } |
581 output << outputBuffer; |
584 else |
582 } |
585 strctPos = 0; |
583 return ret; |
586 |
584 } |
587 if(strctPos == isStruct.length()) |
585 |
588 { |
|
589 strctPos = 0; |
|
590 buf = isStruct; |
|
591 ignorecheck = true; // in the current iteration don't match buf string with class\enum\struct keyword |
|
592 // as keyword may be part of some word like " structural" |
|
593 } |
|
594 |
|
595 if(c == isEnum.at(enmPos) )// searching for enum keyword with space before and after |
|
596 { |
|
597 if( enmPos == 0 ) |
|
598 { |
|
599 if(outputBuffer == "" || outputBuffer.at(bufPos) == ' ' || outputBuffer.at(bufPos) == '\t' |
|
600 || int(outputBuffer.at(bufPos)) == 10 ) |
|
601 enmPos++; |
|
602 } |
|
603 else |
|
604 enmPos++; |
|
605 } |
|
606 else |
|
607 enmPos = 0; |
|
608 |
|
609 if( enmPos == isEnum.length()) |
|
610 { |
|
611 enmPos = 0; |
|
612 buf = isEnum; |
|
613 ignorecheck = true;// in the current iteration don't match buf string with class\enum\struct keyword |
|
614 // as keyword may be part of some word like " enumuration" |
|
615 } |
|
616 |
|
617 if (state == EStateSearching) |
|
618 { |
|
619 memset(stackArray,'\0',MAX_ARRAY_COUNT); |
|
620 if (c == tofind.at(matches)) |
|
621 { |
|
622 matches++; |
|
623 toflush += c; |
|
624 } else |
|
625 { |
|
626 matches = 0; |
|
627 if (!toflush.empty()) |
|
628 { |
|
629 outputBuffer += toflush; |
|
630 toflush = ""; |
|
631 } |
|
632 outputBuffer += c; |
|
633 |
|
634 if(buf.length() > 0 && ignorecheck == false && (c != ' ' && c != '\t' |
|
635 && int(c) != 10 )) |
|
636 { |
|
637 buf = ""; |
|
638 arraychar = '\0'; |
|
639 } |
|
640 } |
|
641 if (matches == tofind.length()) |
|
642 { |
|
643 toflush = ""; |
|
644 state = EStateReplacing; // export keyword match found, so make the stae as replacing |
|
645 matches = 0; |
|
646 } |
|
647 } else if (state == EStateReplacing) |
|
648 { |
|
649 // under a exported class,for a function the exported keyword is present,it should be deleted. |
|
650 if (c == tofind.at(matches)) |
|
651 { |
|
652 matches++; |
|
653 toflush += c; |
|
654 if (matches == tofind.length()) |
|
655 { |
|
656 toflush = ""; |
|
657 matches = 0; |
|
658 } |
|
659 continue; |
|
660 } else |
|
661 { |
|
662 matches = 0; |
|
663 if (!toflush.empty()) |
|
664 { |
|
665 outputBuffer += toflush; |
|
666 toflush = ""; |
|
667 } |
|
668 } |
|
669 |
|
670 |
|
671 if(c == isInline.at(inlinePos)) |
|
672 { |
|
673 if( inlinePos == 0 )// searching for inline keyword with space before and after |
|
674 { |
|
675 if(outputBuffer == "" || outputBuffer.at(bufPos) == ' ' || outputBuffer.at(bufPos) == '\t' |
|
676 || int(outputBuffer.at(bufPos)) == 10 ) |
|
677 inlinePos++; |
|
678 } |
|
679 else |
|
680 inlinePos++; |
|
681 } |
|
682 else |
|
683 inlinePos = 0; |
|
684 |
|
685 if( inlinePos == isInline.length()) |
|
686 { |
|
687 inlinePos = 0; |
|
688 buf = isInline; |
|
689 |
|
690 } |
|
691 |
|
692 if ( buf.length() > 0 && (c == ' ' || c == '\t' || int(c) == 10)) |
|
693 { |
|
694 if (buf == isClass) |
|
695 { |
|
696 arraychar = 'c'; |
|
697 } |
|
698 if (buf == isStruct ) |
|
699 { |
|
700 arraychar = 's'; |
|
701 } |
|
702 if (buf == isEnum) |
|
703 { |
|
704 arraychar = 'e'; |
|
705 } |
|
706 if(buf == isUnion) |
|
707 { |
|
708 arraychar = 'u'; |
|
709 } |
|
710 if(buf == isInline) |
|
711 { |
|
712 stackArray[arryPos] = 'i'; // place inline keyword in stack |
|
713 arryPos++; |
|
714 } |
|
715 |
|
716 buf = ""; |
|
717 if(temp.length() > 0) |
|
718 temp = ""; |
|
719 } |
|
720 else if (c == '{') |
|
721 { |
|
722 // place the keyword in stack for class\enum\struct |
|
723 if(arraychar != '\0') |
|
724 { |
|
725 stackArray[arryPos] = arraychar; |
|
726 arraychar = '\0'; |
|
727 arryPos++; |
|
728 } |
|
729 stackArray[arryPos] = c; |
|
730 arryPos++; |
|
731 |
|
732 if(temp.length() > 0) |
|
733 temp = ""; |
|
734 } |
|
735 else if(c== '}') |
|
736 { |
|
737 temp = ""; |
|
738 bool ignore = false; |
|
739 // can be end of class\enum\struct |
|
740 for (int i = arryPos-1; i >= 0; i-- ) |
|
741 { |
|
742 |
|
743 if (stackArray[i] == '{' ) |
|
744 { |
|
745 if( stackArray[i-1] != 'c' && stackArray[i-1] != 's' |
|
746 && stackArray[i-1] != 'e' && stackArray[i-1] != 'u') |
|
747 // check if the function is inline |
|
748 { |
|
749 |
|
750 ignore = true; |
|
751 break; |
|
752 } |
|
753 } |
|
754 } |
|
755 if(ignore == false) |
|
756 temp = c; |
|
757 |
|
758 stackArray[arryPos] = c; |
|
759 arryPos++; |
|
760 |
|
761 if(temp == "") |
|
762 { |
|
763 int openbraceCount = 0; |
|
764 int closebracecount = 0; |
|
765 |
|
766 // if it is end of a function then delete the entry from stack |
|
767 // and it is ofcourse not a exported function, |
|
768 //will definitely be a inline function with or without "inline" keyword |
|
769 bool deleteEntry = false; |
|
770 int setpos = 0; |
|
771 // get the pos after class\struct\enum started |
|
772 for(int i = arryPos; i >= 0; i--) |
|
773 { |
|
774 if(stackArray[i] == '{') |
|
775 { |
|
776 deleteEntry = true; |
|
777 if (stackArray[i-1] == 'c' || stackArray[i-1] == 's' |
|
778 || stackArray[i-1] == 'e' || stackArray[i-1] == 'u') |
|
779 { |
|
780 setpos = i+1; |
|
781 break; |
|
782 } |
|
783 } |
|
784 } |
|
785 // find the end pos of the non exported function by matching the open and close flower brace count. |
|
786 if(deleteEntry) |
|
787 { |
|
788 deleteEntry = false; |
|
789 for(int i = setpos; i <= arryPos; i++ ) |
|
790 { |
|
791 if(stackArray[i] == '{') |
|
792 openbraceCount++; |
|
793 else if(stackArray[i] == '}') |
|
794 closebracecount++; |
|
795 } |
|
796 if(openbraceCount > 0 && openbraceCount == closebracecount ) |
|
797 { |
|
798 deleteEntry = true;// need to delete the non exported function entry from stack now |
|
799 } |
|
800 } |
|
801 // noe delete the non exported entry and re arrange the stack |
|
802 if(deleteEntry) |
|
803 { |
|
804 for(int pos = setpos; pos <= arryPos; pos++ ) |
|
805 stackArray[pos] = '\0'; |
|
806 |
|
807 arryPos = setpos; |
|
808 } |
|
809 } |
|
810 |
|
811 } |
|
812 else if ( (c == '=' && stackArray[arryPos-1] == ')') || |
|
813 (c == '0' && stackArray[arryPos-1] == '=') || |
|
814 (c == '(' || c == ')' )|| |
|
815 ( possibleVirtualFunc == true ||virtualFunc == true) |
|
816 ) // can be a virtual function or normal function which might be exported |
|
817 { |
|
818 if(temp.length() > 0) |
|
819 temp = ""; |
|
820 |
|
821 if( (possibleVirtualFunc == true && ( c!= '0' && c != ' ' && c != '\t' && int(c) != 10) ) || |
|
822 (virtualFunc == true && (c!= ';' && c != ' ' && c != '\t' && int(c) != 10)) ) |
|
823 { // if other than space and '0', then set posVirtual func to false |
|
824 // or if other than space and ';', then set Virtual func to false |
|
825 outputBuffer += flush; |
|
826 outputBuffer += c; |
|
827 flush = ""; |
|
828 possibleVirtualFunc = false; |
|
829 virtualFunc = false; |
|
830 continue; |
|
831 } |
|
832 |
|
833 else if( c == '=') // possible virtual function |
|
834 { |
|
835 flush = c; |
|
836 possibleVirtualFunc = true; |
|
837 virtualFunc = false; |
|
838 stackArray[arryPos] = c; |
|
839 arryPos++; |
|
840 continue; |
|
841 } |
|
842 else if (possibleVirtualFunc == true) |
|
843 { |
|
844 flush += c; |
|
845 if ( c == '0') |
|
846 { |
|
847 virtualFunc = true; // pure virtual function |
|
848 possibleVirtualFunc = false; |
|
849 stackArray[arryPos] = c; |
|
850 arryPos++; |
|
851 } |
|
852 continue; |
|
853 } |
|
854 else if (c == '(' || c == ')') |
|
855 { |
|
856 flush = ""; |
|
857 stackArray[arryPos] = c; |
|
858 arryPos++; |
|
859 } |
|
860 |
|
861 } |
|
862 |
|
863 if (c == ';') |
|
864 { |
|
865 arraychar = '\0'; |
|
866 // first check for inline function and delete the entry from stack for this func |
|
867 bool isinline = false; |
|
868 bool nonExpFun = false; |
|
869 bool removeEntry = false; |
|
870 |
|
871 for (int i = arryPos-1; i >= 0; i-- ) |
|
872 { |
|
873 if ( stackArray[i] == 'i') // inline function with inline keyword |
|
874 isinline = true; |
|
875 |
|
876 else if (stackArray[i] == '{')// check if the function is inline |
|
877 { |
|
878 if (stackArray[i-1] != 'c' && stackArray[i-1] != 's' |
|
879 && stackArray[i-1] != 'e' && stackArray[i-1] != 'u') |
|
880 nonExpFun = true; |
|
881 } |
|
882 } |
|
883 |
|
884 // end of struct/class/enum |
|
885 if (stackArray[arryPos-1] == '}' && temp == "}" ) |
|
886 { |
|
887 //if(!isinline && !nonExpFun) |
|
888 { |
|
889 int cnt = arryPos-1; |
|
890 bool flag = false; |
|
891 for (int i = cnt; i>=0; i--) |
|
892 { |
|
893 if (stackArray[i] == 'c' || stackArray[i] == 's' |
|
894 || stackArray[i] == 'e' || stackArray[i] == 'u') |
|
895 { |
|
896 flag = true; |
|
897 } |
|
898 stackArray[i] = '\0'; |
|
899 arryPos--; |
|
900 if( flag ) |
|
901 { |
|
902 break; |
|
903 } |
|
904 } |
|
905 outputBuffer += c; |
|
906 temp = ""; |
|
907 |
|
908 if(stackArray[0] == '\0') // check if exported class\struct is ended .. |
|
909 // set state to searching and continue; |
|
910 state = EStateSearching; |
|
911 continue; |
|
912 } |
|
913 } |
|
914 |
|
915 if(stackArray[arryPos-1] == '('&& nonExpFun == false && isinline == false) |
|
916 // not function, can be a for loop, so reset the stackArray ... |
|
917 { |
|
918 outputBuffer += c; |
|
919 removeEntry = true; |
|
920 } |
|
921 else if(stackArray[arryPos-1] == ')' ) |
|
922 // some exported function can be "abcd( xyz(0), pqr(0))" |
|
923 { |
|
924 if( nonExpFun == false && isinline == false ) |
|
925 { |
|
926 outputBuffer += " "; |
|
927 outputBuffer += attribstr; |
|
928 } |
|
929 outputBuffer += c; |
|
930 if (nonExpFun == false) |
|
931 removeEntry = true; |
|
932 } |
|
933 else if( (stackArray[arryPos-1] == '0' && stackArray[arryPos-2] == '=' && virtualFunc == true) ) |
|
934 { // can be a virtual function or normal function which is definitely exported |
|
935 if(!isinline && !nonExpFun) |
|
936 { |
|
937 outputBuffer += " "; |
|
938 outputBuffer += attribstr; |
|
939 outputBuffer += " "; |
|
940 } |
|
941 outputBuffer += flush; |
|
942 outputBuffer += c; |
|
943 flush = ""; |
|
944 if(nonExpFun == false) |
|
945 removeEntry = true; |
|
946 virtualFunc = false; |
|
947 } |
|
948 else |
|
949 { |
|
950 outputBuffer += c; |
|
951 } |
|
952 |
|
953 if(removeEntry == true) |
|
954 { |
|
955 int cnt = arryPos-1; |
|
956 bool flag = false; |
|
957 for (int i = cnt; i>=0; i--) |
|
958 { |
|
959 if (stackArray[i] == '{' && |
|
960 (stackArray[i-1] == 'c' || stackArray[i-1] == 's' |
|
961 || stackArray[i-1] == 'e' || stackArray[i-1] == 'u') ) |
|
962 flag = true; |
|
963 |
|
964 if(flag == false) |
|
965 { |
|
966 stackArray[i] = '\0'; |
|
967 arryPos--; |
|
968 } |
|
969 } |
|
970 } |
|
971 |
|
972 if(stackArray[0] == '\0') |
|
973 state = EStateSearching; |
|
974 } |
|
975 else |
|
976 { |
|
977 if( virtualFunc == true ) |
|
978 { |
|
979 outputBuffer += flush; |
|
980 flush = ""; |
|
981 virtualFunc = false; |
|
982 } |
|
983 outputBuffer += c; |
|
984 } |
|
985 } else if (state == EStateReplaceDone) |
|
986 { |
|
987 |
|
988 } |
|
989 |
|
990 } |
|
991 if (outputBuffer.length() != 0) |
|
992 { |
|
993 output << outputBuffer; |
|
994 } |
|
995 return ret; |
|
996 } |
586 |
997 |
587 // ---------------------------------------------------------------------------- |
998 // ---------------------------------------------------------------------------- |
588 // CPPParser::ReplaceExport |
999 // CPPParser::ReplaceExport |
589 // ---------------------------------------------------------------------------- |
1000 // ---------------------------------------------------------------------------- |
590 // |
1001 // |