Changeset 96401 in vbox for trunk/src/bldprogs/scmparser.cpp
- Timestamp:
- Aug 22, 2022 3:06:19 PM (3 years ago)
- svn:sync-xref-src-repo-rev:
- 153218
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/bldprogs/scmparser.cpp
r93115 r96401 95 95 96 96 97 /** Macro for checking for a XML comment start. */ 98 #define IS_XML_COMMENT_START(a_pch, a_off, a_cch) \ 99 ( (a_off) + 4 <= (a_cch) \ 100 && (a_pch)[(a_off) ] == '<' \ 101 && (a_pch)[(a_off) + 1] == '!' \ 102 && (a_pch)[(a_off) + 2] == '-' \ 103 && (a_pch)[(a_off) + 3] == '-' \ 104 && ((a_off) + 4 == (a_cch) || RT_C_IS_SPACE((a_pch)[(a_off) + 4])) ) 105 106 /** Macro for checking for a XML comment end. */ 107 #define IS_XML_COMMENT_END(a_pch, a_off, a_cch) \ 108 ( (a_off) + 3 <= (a_cch) \ 109 && (a_pch)[(a_off) ] == '-' \ 110 && (a_pch)[(a_off) + 1] == '-' \ 111 && (a_pch)[(a_off) + 2] == '>') 112 113 97 114 /** Macro for checking for a batch file comment prefix. */ 98 115 #define IS_REM(a_pch, a_off, a_cch) \ … … 199 216 off += cchSkip; 200 217 201 /* Determin comment type. */218 /* Determine comment type. */ 202 219 Info.enmType = kScmCommentType_Line; 203 220 char ch; … … 340 357 341 358 /** 342 * Common string lit teral handler.359 * Common string literal handler. 343 360 * 344 361 * @returns new pchLine value. … … 352 369 * @param poff Pointer to the line offset variable. 353 370 */ 354 static const char *handleStringLit teral(PSCMSTREAM pIn, char chType, const char *pchLine, size_t *pcchLine, PSCMEOL penmEol,355 371 static const char *handleStringLiteral(PSCMSTREAM pIn, char chType, const char *pchLine, size_t *pcchLine, PSCMEOL penmEol, 372 uint32_t *piLine, size_t *poff) 356 373 { 357 374 size_t off = *poff; … … 443 460 Info.cBlankLinesBefore = 0; 444 461 445 /* Determin comment type (same as for line-comments). */462 /* Determine comment type (same as for line-comments). */ 446 463 Info.enmType = kScmCommentType_MultiLine; 447 464 if ( off < cchLine … … 594 611 { 595 612 /* 596 * String lit teralsmay include sequences that looks like comments. So,613 * String literal may include sequences that looks like comments. So, 597 614 * they needs special handling to avoid confusion. 598 615 */ 599 pchLine = handleStringLit teral(pIn, '"', pchLine, &cchLine, &enmEol, &iLine, &off);616 pchLine = handleStringLiteral(pIn, '"', pchLine, &cchLine, &enmEol, &iLine, &off); 600 617 } 601 /* else: We don't have to deal with character lit teralsas these shouldn't618 /* else: We don't have to deal with character literal as these shouldn't 602 619 include comment-like sequences. */ 603 620 } /* for each character in the line */ … … 659 676 { 660 677 /* 661 * String lit teralsmay be doc strings and they may legally include hashes.678 * String literal may be doc strings and they may legally include hashes. 662 679 */ 663 680 const char chType = ch; … … 665 682 || pchLine[off] != chType 666 683 || pchLine[off + 1] != chType) 667 pchLine = handleStringLit teral(pIn, chType, pchLine, &cchLine, &enmEol, &iLine, &off);684 pchLine = handleStringLiteral(pIn, chType, pchLine, &cchLine, &enmEol, &iLine, &off); 668 685 else 669 686 { … … 806 823 break; 807 824 } 808 /* else: We don't have to deal with character lit teralsas these shouldn't825 /* else: We don't have to deal with character literal as these shouldn't 809 826 include comment-like sequences. */ 827 } /* for each character in the line */ 828 829 iLine++; 830 } /* for each line in the stream */ 831 832 int rcStream = ScmStreamGetStatus(pIn); 833 if (RT_SUCCESS(rcStream)) 834 return rcRet; 835 return rcStream; 836 } 837 838 839 /** 840 * Deals with XML comments. 841 * 842 * @returns VBox status code / callback return code. 843 * @param pIn The stream to parse. 844 * @param pfnCallback The callback. 845 * @param pvUser The user parameter for the callback. 846 */ 847 static int enumerateXmlComments(PSCMSTREAM pIn, PFNSCMCOMMENTENUMERATOR pfnCallback, void *pvUser) 848 { 849 int rcRet = VINF_SUCCESS; 850 uint32_t iLine = 0; 851 SCMEOL enmEol; 852 size_t cchLine; 853 const char *pchLine; 854 while ((pchLine = ScmStreamGetLine(pIn, &cchLine, &enmEol)) != NULL) 855 { 856 size_t off = 0; 857 while (off < cchLine) 858 { 859 /* 860 * Skip leading blanks and check for start of XML comment. 861 */ 862 while (off + 3 < cchLine && RT_C_IS_SPACE(pchLine[off])) 863 off++; 864 if (IS_XML_COMMENT_START(pchLine, off, cchLine)) 865 { 866 /* 867 * XML comment. Find the end. 868 * 869 * Note! This is very similar to the python doc string handling above. 870 */ 871 SCMCOMMENTINFO Info; 872 Info.iLineStart = iLine; 873 Info.offStart = (uint32_t)off; 874 Info.iLineEnd = UINT32_MAX; 875 Info.offEnd = UINT32_MAX; 876 Info.cBlankLinesBefore = 0; 877 Info.enmType = kScmCommentType_Xml; 878 879 off += 4; 880 881 /* 882 * Copy the body and find the end of the XML comment. 883 */ 884 size_t cbBodyAlloc = 0; 885 size_t cchBody = 0; 886 char *pszBody = NULL; 887 for (;;) 888 { 889 /* Parse the line up to the end-of-comment or end-of-line. */ 890 size_t offLineStart = off; 891 size_t offLastNonBlank = off; 892 size_t offFirstNonBlank = ~(size_t)0; 893 while (off < cchLine) 894 { 895 if (!IS_XML_COMMENT_END(pchLine, off, cchLine)) 896 { 897 char ch = pchLine[off++]; 898 if (RT_C_IS_BLANK(ch)) 899 {/* kind of likely */} 900 else 901 { 902 offLastNonBlank = off - 1; 903 if (offFirstNonBlank != ~(size_t)0) 904 {/* likely */} 905 else if ( (ch != '*' && ch != '#') /* ignore continuation-asterisks */ 906 || off > Info.offStart + 1 + 1 907 || off > cchLine 908 || ( off < cchLine 909 && !RT_C_IS_SPACE(pchLine[off])) 910 || pszBody == NULL) 911 offFirstNonBlank = off - 1; 912 } 913 } 914 else 915 { 916 off += 3; 917 Info.offEnd = (uint32_t)off; 918 Info.iLineEnd = iLine; 919 break; 920 } 921 } 922 923 /* Append line content to the comment body string. */ 924 size_t cchAppend; 925 if (offFirstNonBlank == ~(size_t)0) 926 cchAppend = 0; /* empty line */ 927 else 928 { 929 offLineStart = offFirstNonBlank; 930 cchAppend = offLastNonBlank + 1 - offLineStart; 931 Assert(cchAppend <= cchLine); 932 } 933 934 size_t cchNewBody = cchBody + (cchBody > 0) + cchAppend; 935 if (cchNewBody >= cbBodyAlloc) 936 { 937 cbBodyAlloc = RT_MAX(cbBodyAlloc ? cbBodyAlloc * 2 : _1K, RT_ALIGN_Z(cchNewBody + 64, 128)); 938 void *pvNew = RTMemRealloc(pszBody, cbBodyAlloc); 939 if (pvNew) 940 pszBody = (char *)pvNew; 941 else 942 { 943 RTMemFree(pszBody); 944 return VERR_NO_MEMORY; 945 } 946 } 947 948 if (cchBody > 0) /* no leading blank lines */ 949 pszBody[cchBody++] = '\n'; 950 else if (cchAppend == 0) 951 Info.cBlankLinesBefore++; 952 memcpy(&pszBody[cchBody], &pchLine[offLineStart], cchAppend); 953 cchBody += cchAppend; 954 pszBody[cchBody] = '\0'; 955 956 /* Advance to the next line, if we haven't yet seen the end of this comment. */ 957 if (Info.iLineEnd != UINT32_MAX) 958 break; 959 pchLine = ScmStreamGetLine(pIn, &cchLine, &enmEol); 960 if (!pchLine) 961 { 962 Info.offEnd = (uint32_t)cchLine; 963 Info.iLineEnd = iLine; 964 break; 965 } 966 iLine++; 967 off = 0; 968 } 969 970 /* Strip trailing empty lines in the body. */ 971 Info.cBlankLinesAfter = 0; 972 while (cchBody >= 1 && pszBody[cchBody - 1] == '\n') 973 { 974 Info.cBlankLinesAfter++; 975 pszBody[--cchBody] = '\0'; 976 } 977 978 /* Do the callback. */ 979 int rc = pfnCallback(&Info, pszBody, cchBody, pvUser); 980 RTMemFree(pszBody); 981 if (RT_FAILURE(rc)) 982 return rc; 983 if (rc > VINF_SUCCESS && rcRet == VINF_SUCCESS) 984 rcRet = rc; 985 } 986 else 987 off++; 810 988 } /* for each character in the line */ 811 989 … … 839 1017 /* 840 1018 * Skip leading blanks and check for 'rem'. 841 * At the moment we do not parse '::lab le-comments'.1019 * At the moment we do not parse '::label-comments'. 842 1020 */ 843 1021 size_t off = 0; … … 1002 1180 return enumerateSimpleLineComments(pIn, '\'', isTickComment, pfnCallback, pvUser); 1003 1181 1182 case kScmCommentStyle_Xml: 1183 return enumerateXmlComments(pIn, pfnCallback, pvUser); 1184 1004 1185 default: 1005 1186 AssertFailedReturn(VERR_INVALID_PARAMETER);
Note:
See TracChangeset
for help on using the changeset viewer.