377 std::ifstream ifstream;
381 if ( !ifstream.is_open() || errno ) {
399 ALIB_ASSERT_ERROR(parser.line.StartsWith(
"<?xml version='1.0'"),
"DXL/TAGFILE",
"Unknown file format")
402 parser.nextTag(
"tagfile");
403 Lox_Info(
"Doxygen version: ", parser.getAttr(
"doxygen_version") )
404 while( !reader.
IsEOF() ) {
408 if (parser.line.Equals(
"</tagfile>"))
412 if ( parser.tryTag(
"compound").IsNull() ) {
414 FilePath, parser.lineNo,
"compound", parser.line);
419 Substring kindStr= parser.getAttr(
"kind");
421 Lox_Error(
"Unknown compound type {!Q} @ {}:{}", kindStr,
FilePath, parser.lineNo)
424 if (parser.line.Equals(
"</compound>") )
433 String1K compoundTagName = parser.nextTag(
"name");
434 String compoundHtmlFile= parser.allocNextTag(
"filename");
440 int templateArgsSize= 0;
444 Substring compoundNameWithoutTemplateParams= compoundTagName;
445 Substring templateSpecializationArgs=
nullptr;
449 compoundNameWithoutTemplateParams= compoundTagName.
Substring(0, templateStart);
450 compoundNameWithoutTemplateParams.
TrimEnd();
451 templateSpecializationArgs = compoundTagName.
Substring(templateStart);
456 String compoundPathPortion=
nullptr;
458 if ( lastPathPos>=0 ) {
460 "Single colon ':' found in compound name {!Q}", compoundTagName )
461 compoundPathPortion= compoundTagName.
Substring(0, lastPathPos -1);
462 compoundNameWithoutTemplateParams= compoundNameWithoutTemplateParams.
Substring(lastPathPos + 1);
471 Cursor component= pathCursor.CreateChild(pathComponent,
nullptr);
475 if ( component.IsValid()) {
477 pathCursor= component;
480 pathCursor.GoToChild(tok.
Actual);
490 Cursor compoundCursor= pathCursor.CreateChild(compoundKey,
nullptr);
491 if ( compoundCursor.IsInvalid()) {
492 compoundCursor= pathCursor.Child(compoundKey);
496 compoundKey, compoundPathPortion,
FilePath,
497 pathCursor.Child(compoundKey).Value()->LineNo, parser.lineNo);
504 compoundCursor.Value()=
505 tagNamespace=
ma().New<
TGTNamespace>(compoundHtmlFile, parser.lineNo);
509 compoundCursor.Value()=
510 tagRecord=
ma().New<
TGTRecord>(
ma, kind, compoundHtmlFile, parser.lineNo);
526 parser.addDocAnchors(compoundCursor);
528 if ( parser.line.StartsWith(
"<member kind=") ) {
530 TGTMember* member= parser.readMember(key, kind);
531 if (!member)
continue;
533 Cursor memberChild= compoundCursor.CreateChild(key, member);
534 if ( memberChild.IsInvalid() ) {
535 Target* existingValue= compoundCursor.Child(key).Value();
544 Lox_Error(
"Doubly defined member function.\n"
545 "This happens with overloaded template functions that use keyword requires.\n"
546 "To fix this, dox only one function and include in the dox that\n"
547 "different versions for different requirements exist.\n"
548 " Function: {}::{}.\n"
549 " Tag-file first occurence: {}:{}.\n"
550 " Tag-file this occurence: {2}:{}.\n"
579 parser.addDocAnchors(memberChild);
582 while (parser.line.StartsWith(
"<enumvalue")) {
583 int lNo= parser.lineNo;
584 String256 elemName= parser.parseTag(
"enumvalue");
586 String(
ma, parser.parseAttr(
"file")), lNo );
588 Cursor elementCursor= memberChild.CreateChild(elemName, enumElementTag);
589 if ( elementCursor.IsInvalid() ) {
591 elemName, compoundPathPortion,
FilePath,
592 memberChild.Child(elemName).Value()->LineNo, parser.lineNo );
598 if (!parser.line.Equals(
"</member>"))
600 FilePath,parser.lineNo,
"/member", parser.line);
607 if ( parser.line.StartsWith(
"<templarg" ) ){
608 templateArgs[templateArgsSize++]=
615 if ( parser.line.StartsWith(
"<class" )
616 && parser.line.EndsWith(
"</class>") )
continue;
618 if ( parser.line.Equals(
"</compound>") )
break;
621 if ( parser.line.StartsWith(
"<base" ) ) {
623 "Base type information found for non-record type")
624 tagRecord->
BaseTypes.push_back(parser.allocTag(
"base"));
629 if ( parser.line.StartsWith(
"<namespace" ) )
continue;
630 if ( parser.line.StartsWith(
"<concept" ) )
continue;
634 FilePath,parser.lineNo,
"/compound", parser.line);
638 if (templateArgsSize) {
640 "Template args found for non-record type")
644 for (
int i= 0; i<templateArgsSize; ++i)
653 path = parser.nextTag(
"path");
655 dirCursor.GoToCreatedPathIfNotExistent(path, &filePathComponentTag);
658 dirCursor= dirCursor.CreateChild(name,
ma().New<TGTDir>( parser.allocNextTag(
"filename"),
663 parser.addDocAnchors(dirCursor);
667 if ( parser.line.StartsWith(
"<file>") )
continue;
668 if ( parser.line.StartsWith(
"<dir>") )
continue;
669 if ( parser.line.Equals(
"</compound>") )
674 FilePath,parser.lineNo,
"/compound", parser.line);
682 path = parser.nextTag(
"path");
684 fileCursor.GoToCreatedPathIfNotExistent(path, &filePathComponentTag);
692 fileCursor= fileCursor.CreateChild(name,
ma().New<TGTFile>(
693 parser.allocNextTag(
"filename"), parser.lineNo));
696 parser.addDocAnchors(fileCursor);
698 if ( parser.line.StartsWith(
"<member kind=") ) {
700 TGTMember* member= parser.readMember(key, kind);
701 if (!member)
continue;
702 Cursor memberChild= fileCursor.CreateChild(key, member);
703 if ( memberChild.IsInvalid() ) {
704 fileCursor.AssemblePath(path);
706 Cursor previous= fileCursor.Child(key);
712 || !previous.Value()->HTMLFile.Equals(member->
HTMLFile) ) {
715 "This happens when a preprocessor constant or macro is defined twice within\n"
716 "the same source file. This is not supported by Doxygen.\n"
717 "Instead, exclude the second (and further) occurrences in the same file from\n"
718 "doxygen and add all different uses to the first definition.\n"
719 " Preprocessor define: {}::{}.\n"
720 " Tag-file first occurence: {}:{}.\n"
721 " Tag-file this occurence: {2}:{}.\n"
723 , previous.Value()->LineNo
726 Lox_Error(
"Doubly defined member {!Q} in tag-file path {}:1\n"
727 " First definition @ {}:{}\n"
728 " Second definition @ {2}:{}", key, path,
FilePath,
729 previous.Value()->LineNo, member->
LineNo)
738 previous.Value()->LineNo, member->
LineNo);
743 parser.addDocAnchors(memberChild);
748 if ( parser.line.Equals(
"</compound>") )
759 if ( parser.line.StartsWith(
"<includes" ) )
continue;
760 if ( parser.line.StartsWith(
"<concept" ) )
continue;
761 if ( parser.line.StartsWith(
"<class" ) )
continue;
762 if ( parser.line.StartsWith(
"<namespace" ) )
continue;
766 FilePath,parser.lineNo,
"/compound", parser.line);
772 String title = parser.allocNextTag(
"title");
775 Cursor groupCursor=
Root().CreateChild(name,
ma().New<TGTGroup>(
776 parser.allocNextTag(
"filename"), parser.lineNo, title));
779 parser.addDocAnchors(groupCursor);
782 if ( parser.line.StartsWith(
"<member kind=") ) {
784 TGTMember* member= parser.readMember(key, kind);
785 if (!member)
continue;
787 Cursor memberChild= groupCursor.CreateChild(key, member);
788 if ( memberChild.IsInvalid() ) {
790 groupCursor.AssemblePath(path);
791 Cursor previous= groupCursor.Child(key);
792 Lox_Warning(
"Doubly defined member {!Q} in tag-file path {}:1\n"
793 " First definition @ {}:{}\n"
794 " Second definition @ {2}:{}"
796 ,previous.Value()->LineNo, member->
LineNo )
800 parser.addDocAnchors(memberChild);
805 if ( parser.line.Equals(
"</compound>") )
816 FilePath,parser.lineNo,
"/compound", parser.line);
822 String title = parser.allocNextTag(
"title");
825 Cursor pageCursor=
Root().CreateChild(name,
ma().New<TGTPage>(
826 parser.allocNextTag(
"filename"), parser.lineNo, title));
830 parser.addDocAnchors(pageCursor);
832 if ( parser.line.Equals(
"</compound>") )
836 FilePath,parser.lineNo,
"/compound", parser.line);
845 auto htmlFile= parser.allocNextTag(
"filename");
848 int qtyCreated= cursor.GoToCreatedPathIfNotExistent(name, &filePathComponentTag);
849 if ( qtyCreated == 0 ) {
850 Cursor previous= cursor.Child(name);
852 || previous.Value()->HTMLFile.Equals(htmlFile) )
854 name,
FilePath, previous.Value()->LineNo, parser.lineNo);
856 " First definition @ {}:{}\n"
857 " Second definition @ {2}:{}",
858 name,
FilePath, previous.Value()->LineNo, parser.lineNo)
862 cursor.Value()=
ma().New<
TGTModule>(htmlFile, parser.lineNo);
864 if (!parser.line.Equals(
"</compound>"))
866 FilePath, parser.lineNo,
"/compound", parser.line);
871 auto htmlFile= parser.allocNextTag(
"filename");
874 int qtyCreated= cursor.GoToCreatedPathIfNotExistent(name, &filePathComponentTag);
875 if ( qtyCreated == 0 ) {
876 Cursor previous= cursor.Child(name);
878 || previous.Value()->HTMLFile.Equals(htmlFile) )
880 name,
FilePath, previous.Value()->LineNo, parser.lineNo);
882 " First definition @ {}:{}\n"
883 " Second definition @ {2}:{}",
884 name,
FilePath, previous.Value()->LineNo, parser.lineNo)
888 cursor.Value()=
ma().New<
TGTConcept>(htmlFile, parser.lineNo);
890 if (!parser.line.Equals(
"</compound>"))
892 FilePath, parser.lineNo,
"/compound", parser.line);
902 Lox_Verbose(
"Finished reading tag-file: {}, maximum line width: ",
FilePath, parser.maxWidth )
903 ALIB_ASSERT_ERROR(parser.maxWidth < 1024,
"DXL/TAGFILE",
"Line buffer to small.")