Doxygen
Loading...
Searching...
No Matches
tagreader.cpp
Go to the documentation of this file.
1/******************************************************************************
2 *
3 * Copyright (C) 1997-2023 by Dimitri van Heesch.
4 *
5 * Permission to use, copy, modify, and distribute this software and its
6 * documentation under the terms of the GNU General Public License is hereby
7 * granted. No representations are made about the suitability of this software
8 * for any purpose. It is provided "as is" without express or implied warranty.
9 * See the GNU General Public License for more details.
10 *
11 * Documents produced by Doxygen are derivative works derived from the
12 * input used in their production; they are not affected by this license.
13 *
14 */
15
16#include "tagreader.h"
17
18#include <map>
19#include <functional>
20#include <utility>
21#include <algorithm>
22#include <variant>
23
24#include <assert.h>
25#include <stdio.h>
26#include <stdarg.h>
27
28#include "xml.h"
29#include "entry.h"
30#include "doxygen.h"
31#include "util.h"
32#include "message.h"
33#include "defargs.h"
34#include "arguments.h"
35#include "filedef.h"
36#include "filename.h"
37#include "section.h"
38#include "containers.h"
39#include "debug.h"
40#include "anchor.h"
41#include "moduledef.h"
42
43// ----------------- private part -----------------------------------------------
44
45namespace {
46
47/** Information about an linkable anchor */
49{
50 public:
52 const QCString &l,
53 const QCString &t=QCString())
54 : label(l), fileName(f), title(t) {}
58};
59
60/** Container for enum values that are scoped within an enum */
69
70/** Container for include info that can be read from a tagfile */
82
83/** Container for member specific info that can be read from a tagfile */
101
102/** Base class for all compound types */
104{
105 std::vector<TagMemberInfo> members;
108 std::vector<TagAnchorInfo> docAnchors;
109 int lineNr = 0;
110};
111
112
113/** Container for class specific info that can be read from a tagfile */
126
127using TagClassInfoPtr = std::unique_ptr<TagClassInfo>;
128
129/** Container for concept specific info that can be read from a tagfile */
134
135using TagConceptInfoPtr = std::unique_ptr<TagConceptInfo>;
136
137/** Container for module specific info that can be read from a tagfile */
142
143using TagModuleInfoPtr = std::unique_ptr<TagModuleInfo>;
144
145
146/** Container for namespace specific info that can be read from a tagfile */
154
155using TagNamespaceInfoPtr = std::unique_ptr<TagNamespaceInfo>;
156
157/** Container for package specific info that can be read from a tagfile */
162
163using TagPackageInfoPtr = std::unique_ptr<TagPackageInfo>;
164
165/** Container for file specific info that can be read from a tagfile */
174
175using TagFileInfoPtr = std::unique_ptr<TagFileInfo>;
176
177/** Container for group specific info that can be read from a tagfile */
190
191using TagGroupInfoPtr = std::unique_ptr<TagGroupInfo>;
192
193/** Container for page specific info that can be read from a tagfile */
199
200using TagPageInfoPtr = std::unique_ptr<TagPageInfo>;
201
202/** Container for directory specific info that can be read from a tagfile */
209
210using TagDirInfoPtr = std::unique_ptr<TagDirInfo>;
211
212/** Variant class that holds a unique pointer to one of the specific container types */
214{
215 public:
216 using VariantT = std::variant< std::monostate, // 0
217 TagClassInfoPtr, // 1
221 TagFileInfoPtr, // 5
222 TagGroupInfoPtr, // 6
223 TagPageInfoPtr, // 7
224 TagDirInfoPtr, // 8
225 TagModuleInfoPtr>; // 9
226
227 enum class Type : uint8_t
228 {
230 Class = 1,
234 File = 5,
235 Group = 6,
236 Page = 7,
237 Dir = 8,
239 };
240
242 explicit TagCompoundVariant(VariantT &&v) : m_variant(std::move(v)) {}
248
249 /** Generic non-const getter */
250 template<class R>
251 R *get()
252 {
253 std::unique_ptr<R> *p = std::get_if<std::unique_ptr<R>>(&m_variant);
254 return p ? p->get() : nullptr;
255 }
256 /** Generic const getter */
257 template<class R>
258 const R *get() const
259 {
260 const std::unique_ptr<R> *p = std::get_if<std::unique_ptr<R>>(&m_variant);
261 return p ? p->get() : nullptr;
262 }
263
264 /** Generic factory method to create a variant holding a unique pointer to a given compound type */
265 template<class R,typename... Args>
266 static TagCompoundVariant make(Args&&... args)
267 {
268 return TagCompoundVariant(VariantT(std::make_unique<R>(std::forward<Args>(args)...)));
269 }
270
271 /** @name convenience const and non-const getters for each variant component
272 * @{
273 */
275 const TagClassInfo *getClassInfo() const { return get<TagClassInfo >(); }
283 const TagFileInfo *getFileInfo() const { return get<TagFileInfo >(); }
285 const TagGroupInfo *getGroupInfo() const { return get<TagGroupInfo >(); }
287 const TagPageInfo *getPageInfo() const { return get<TagPageInfo >(); }
289 const TagDirInfo *getDirInfo() const { return get<TagDirInfo >(); }
292 /** @} */
293
294 /** Convenience method to get the shared compound info */
296 {
297 switch(type())
298 {
299 case Type::Uninitialized: return nullptr;
300 case Type::Class: return getClassInfo();
301 case Type::Concept: return getConceptInfo();
302 case Type::Namespace: return getNamespaceInfo();
303 case Type::Package: return getPackageInfo();
304 case Type::File: return getFileInfo();
305 case Type::Group: return getGroupInfo();
306 case Type::Page: return getPageInfo();
307 case Type::Dir: return getDirInfo();
308 case Type::Module: return getModuleInfo();
309 }
310 return nullptr;
311 }
312 Type type() const
313 {
314 return static_cast<Type>(m_variant.index());
315 }
316
317 private:
319};
320
321
322/** Tag file parser.
323 *
324 * Reads an XML-structured tagfile and builds up the structure in
325 * memory. The method buildLists() is used to transfer/translate
326 * the structures to the doxygen engine.
327 */
329{
330#define p_warn(fmt,...) do { \
331 warn(m_locator->fileName(),m_locator->lineNr(),fmt,##__VA_ARGS__); \
332 } while(0)
333
334 public:
335
336 explicit TagFileParser(const char *tagName) : m_tagName(tagName) {}
337
338 void setDocumentLocator ( const XMLLocator * locator )
339 {
340 m_locator = locator;
341 }
342
344 {
346 }
347
348 void startElement( const QCString &name, const XMLHandlers::Attributes& attrib );
349 void endElement( const QCString &name );
350 void characters ( const QCString & ch ) { m_curString+=ch; }
351 void error( const QCString &fileName,int lineNr,const QCString &msg)
352 {
353 warn(fileName,lineNr,"{}",msg);
354 }
355
356 void dump();
357 void buildLists(const std::shared_ptr<Entry> &root);
358 void addIncludes();
359 void startCompound( const XMLHandlers::Attributes& attrib );
360
362 {
363 switch (m_state)
364 {
365 case InClass:
366 case InConcept:
367 case InFile:
368 case InNamespace:
369 case InGroup:
370 case InPage:
371 case InDir:
372 case InModule:
373 case InPackage:
374 m_tagFileCompounds.push_back(std::move(m_curCompound));
375 break;
376 default:
377 p_warn("tag 'compound' was not expected!");
378 break;
379 }
380 }
381
383 {
385 m_curMember.kind = XMLHandlers::value(attrib,"kind");
386 QCString protStr = XMLHandlers::value(attrib,"protection");
387 QCString virtStr = XMLHandlers::value(attrib,"virtualness");
388 QCString staticStr = XMLHandlers::value(attrib,"static");
389 m_curMember.lineNr = m_locator->lineNr();
390 if (protStr=="protected")
391 {
393 }
394 else if (protStr=="private")
395 {
397 }
398 if (virtStr=="virtual")
399 {
401 }
402 else if (virtStr=="pure")
403 {
405 }
406 if (staticStr=="yes")
407 {
408 m_curMember.isStatic = TRUE;
409 }
410 m_stateStack.push(m_state);
412 }
413
415 {
416 m_state = m_stateStack.top();
417 m_stateStack.pop();
418 switch(m_state)
419 {
420 case InClass:
421 case InFile:
422 case InNamespace:
423 case InGroup:
424 case InPackage:
425 {
426 TagCompoundInfo *info = m_curCompound.getCompoundInfo();
427 if (info)
428 {
429 info->members.push_back(m_curMember);
430 }
431 }
432 break;
433 default:
434 p_warn("Unexpected tag 'member' found");
435 break;
436 }
437 }
438
440 {
441 if (m_state==InMember)
442 {
443 m_curString = "";
445 m_curEnumValue.file = XMLHandlers::value(attrib,"file");
446 m_curEnumValue.anchor = XMLHandlers::value(attrib,"anchor");
447 m_curEnumValue.clangid = XMLHandlers::value(attrib,"clangid");
448 m_stateStack.push(m_state);
450 }
451 else
452 {
453 p_warn("Found 'enumvalue' tag outside of member tag");
454 }
455 }
456
458 {
460 m_state = m_stateStack.top();
461 m_stateStack.pop();
462 if (m_state==InMember)
463 {
464 m_curMember.enumValues.push_back(m_curEnumValue);
466 }
467 }
468
470 {
471 // Check whether or not the tag is automatically generate, in that case ignore the tag.
472 switch(m_state)
473 {
474 case InClass:
475 case InConcept:
476 case InFile:
477 case InNamespace:
478 case InGroup:
479 case InPage:
480 case InMember:
481 case InPackage:
482 case InDir:
483 case InModule:
485 break;
486 default:
487 p_warn("Unexpected tag 'docanchor' found");
488 return;
489 }
490 switch(m_state)
491 {
492 case InClass:
493 case InConcept:
494 case InFile:
495 case InNamespace:
496 case InGroup:
497 case InPage:
498 case InPackage:
499 case InDir:
500 case InModule:
501 {
502 TagCompoundInfo *info = m_curCompound.getCompoundInfo();
503 if (info)
504 {
505 info->docAnchors.emplace_back(m_fileName,m_curString,m_title);
506 }
507 }
508 break;
509 case InMember:
510 m_curMember.docAnchors.emplace_back(m_fileName,m_curString,m_title);
511 break;
512 default: break; // will not be reached
513 }
514 }
515
516 void endClass()
517 {
518 switch(m_state)
519 {
520 case InClass:
521 {
522 TagClassInfo *info = m_curCompound.getClassInfo();
523 if (info) info->classList.push_back(m_curString.str());
524 }
525 break;
526 case InFile:
527 {
528 TagFileInfo *info = m_curCompound.getFileInfo();
529 if (info) info->classList.push_back(m_curString.str());
530 }
531 break;
532 case InNamespace:
533 {
534 TagNamespaceInfo *info = m_curCompound.getNamespaceInfo();
535 if (info) info->classList.push_back(m_curString.str());
536 }
537 break;
538 case InGroup:
539 {
540 TagGroupInfo *info = m_curCompound.getGroupInfo();
541 if (info) info->classList.push_back(m_curString.str());
542 }
543 break;
544 case InPackage:
545 {
546 TagPackageInfo *info = m_curCompound.getPackageInfo();
547 if (info) info->classList.push_back(m_curString.str());
548 }
549 break;
550 default:
551 p_warn("Unexpected tag 'class' found");
552 break;
553 }
554 }
555
557 {
558 switch(m_state)
559 {
560 case InNamespace:
561 {
562 TagNamespaceInfo *info = m_curCompound.getNamespaceInfo();
563 if (info) info->conceptList.push_back(m_curString.str());
564 }
565 break;
566 case InFile:
567 {
568 TagFileInfo *info = m_curCompound.getFileInfo();
569 if (info) info->conceptList.push_back(m_curString.str());
570 }
571 break;
572 case InGroup:
573 {
574 TagGroupInfo *info = m_curCompound.getGroupInfo();
575 if (info) info->conceptList.push_back(m_curString.str());
576 }
577 break;
578 default:
579 p_warn("Unexpected tag 'concept' found");
580 break;
581 }
582 }
583
585 {
586 switch(m_state)
587 {
588 case InGroup:
589 {
590 TagGroupInfo *info = m_curCompound.getGroupInfo();
591 if (info) info->moduleList.push_back(m_curString.str());
592 }
593 break;
594 default:
595 p_warn("Unexpected tag 'module' found");
596 break;
597 }
598 }
599
601 {
602 switch(m_state)
603 {
604 case InNamespace:
605 {
606 TagNamespaceInfo *info = m_curCompound.getNamespaceInfo();
607 if (info) info->namespaceList.push_back(m_curString.str());
608 }
609 break;
610 case InFile:
611 {
612 TagFileInfo *info = m_curCompound.getFileInfo();
613 if (info) info->namespaceList.push_back(m_curString.str());
614 }
615 break;
616 case InGroup:
617 {
618 TagGroupInfo *info = m_curCompound.getGroupInfo();
619 if (info) info->namespaceList.push_back(m_curString.str());
620 }
621 break;
622 default:
623 p_warn("Unexpected tag 'namespace' found");
624 break;
625 }
626 }
627
628 void endFile()
629 {
630 switch(m_state)
631 {
632 case InGroup:
633 {
634 TagGroupInfo *info = m_curCompound.getGroupInfo();
635 if (info) info->fileList.push_back(m_curString.str());
636 }
637 break;
638 case InDir:
639 {
640 TagDirInfo *info = m_curCompound.getDirInfo();
641 if (info) info->fileList.push_back(m_curString.str());
642 }
643 break;
644 default:
645 p_warn("Unexpected tag 'file' found");
646 break;
647 }
648 }
649
650 void endPage()
651 {
652 switch(m_state)
653 {
654 case InGroup:
655 {
656 TagGroupInfo *info = m_curCompound.getGroupInfo();
657 if (info) info->fileList.push_back(m_curString.str());
658 }
659 break;
660 default:
661 p_warn("Unexpected tag 'page' found");
662 break;
663 }
664 }
665
667 {
668 switch(m_state)
669 {
670 case InPage:
671 {
672 TagPageInfo *info = m_curCompound.getPageInfo();
673 if (info) info->subpages.push_back(m_curString.str());
674 }
675 break;
676 default:
677 p_warn("Unexpected tag 'subpage' found");
678 break;
679 }
680 }
681
682 void endDir()
683 {
684 switch(m_state)
685 {
686 case InDir:
687 {
688 TagDirInfo *info = m_curCompound.getDirInfo();
689 if (info) info->subdirList.push_back(m_curString.str());
690 }
691 break;
692 default:
693 p_warn("Unexpected tag 'dir' found");
694 break;
695 }
696 }
697
699 {
700 m_curString = "";
701 }
702
704 {
705 m_fileName = XMLHandlers::value(attrib,"file");
706 m_title = XMLHandlers::value(attrib,"title");
707 m_curString = "";
708 }
709
710 void endType()
711 {
712 if (m_state==InMember)
713 {
715 }
716 else
717 {
718 p_warn("Unexpected tag 'type' found");
719 }
720 }
721
722 void endName()
723 {
724 switch (m_state)
725 {
726 case InClass:
727 case InConcept:
728 case InFile:
729 case InNamespace:
730 case InGroup:
731 case InPage:
732 case InDir:
733 case InPackage:
734 case InModule:
735 {
736 TagCompoundInfo *info = m_curCompound.getCompoundInfo();
737 if (info) info->name = m_curString;
738 }
739 break;
740 case InMember:
742 break;
743 default:
744 p_warn("Unexpected tag 'name' found");
745 break;
746 }
747 }
748
750 {
751 m_curString="";
752 TagClassInfo *info = m_curCompound.getClassInfo();
753 if (m_state==InClass && info)
754 {
755 QCString protStr = XMLHandlers::value(attrib,"protection");
756 QCString virtStr = XMLHandlers::value(attrib,"virtualness");
759 if (protStr=="protected")
760 {
762 }
763 else if (protStr=="private")
764 {
765 prot = Protection::Private;
766 }
767 if (virtStr=="virtual")
768 {
769 virt = Specifier::Virtual;
770 }
771 info->bases.emplace_back(m_curString,prot,virt);
772 }
773 else
774 {
775 p_warn("Unexpected tag 'base' found");
776 }
777 }
778
779 void endBase()
780 {
781 TagClassInfo *info = m_curCompound.getClassInfo();
782 if (m_state==InClass && info)
783 {
784 info->bases.back().name = m_curString;
785 }
786 else
787 {
788 p_warn("Unexpected tag 'base' found");
789 }
790 }
791
793 {
795 m_curIncludes.id = XMLHandlers::value(attrib,"id");
796 m_curIncludes.name = XMLHandlers::value(attrib,"name");
797 m_curIncludes.isLocal = XMLHandlers::value(attrib,"local")=="yes";
798 m_curIncludes.isImported = XMLHandlers::value(attrib,"imported")=="yes";
799 m_curIncludes.isModule = XMLHandlers::value(attrib,"module")=="yes";
800 m_curIncludes.isObjC = XMLHandlers::value(attrib,"objc")=="yes";
801 m_curString="";
802 }
803
805 {
807 TagFileInfo *info = m_curCompound.getFileInfo();
808 if (m_state==InFile && info)
809 {
810 info->includes.push_back(m_curIncludes);
811 }
812 else
813 {
814 p_warn("Unexpected tag 'includes' found");
815 }
816 }
817
819 {
820 TagClassInfo *info = m_curCompound.getClassInfo();
821 if (m_state==InClass && info)
822 {
823 info->templateArguments.push_back(m_curString.str());
824 }
825 else
826 {
827 p_warn("Unexpected tag 'templarg' found");
828 }
829 }
830
832 {
833 switch (m_state)
834 {
835 case InClass:
836 case InConcept:
837 case InNamespace:
838 case InFile:
839 case InGroup:
840 case InPage:
841 case InPackage:
842 case InDir:
843 case InModule:
844 {
845 TagCompoundInfo *info = m_curCompound.getCompoundInfo();
846 if (info) info->filename = m_curString;
847 }
848 break;
849 default:
850 p_warn("Unexpected tag 'filename' found");
851 break;
852 }
853 }
854
855 void endPath()
856 {
857 switch (m_state)
858 {
859 case InFile:
860 {
861 TagFileInfo *info = m_curCompound.getFileInfo();
862 if (info) info->path = m_curString;
863 }
864 break;
865 case InDir:
866 {
867 TagDirInfo *info = m_curCompound.getDirInfo();
868 if (info) info->path = m_curString;
869 }
870 break;
871 default:
872 p_warn("Unexpected tag 'path' found");
873 break;
874 }
875 }
876
878 {
879 if (m_state==InMember)
880 {
881 m_curMember.anchor = m_curString;
882 }
883 else if (m_state==InClass)
884 {
885 TagClassInfo *info = m_curCompound.getClassInfo();
886 if (info) info->anchor = m_curString;
887 }
888 else
889 {
890 p_warn("Unexpected tag 'anchor' found");
891 }
892 }
893
895 {
896 if (m_state==InMember)
897 {
898 m_curMember.clangId = m_curString;
899 }
900 else if (m_state==InClass)
901 {
902 TagClassInfo *info = m_curCompound.getClassInfo();
903 if (info) info->clangId = m_curString;
904 }
905 else if (m_state==InNamespace)
906 {
907 TagNamespaceInfo *info = m_curCompound.getNamespaceInfo();
908 if (info) info->clangId = m_curString;
909 }
910 else
911 {
912 p_warn("Unexpected tag 'clangid' found");
913 }
914 }
915
916
917
919 {
920 if (m_state==InMember)
921 {
922 m_curMember.anchorFile = m_curString;
923 }
924 else
925 {
926 p_warn("Unexpected tag 'anchorfile' found");
927 }
928 }
929
931 {
932 if (m_state==InMember)
933 {
934 m_curMember.arglist = m_curString;
935 }
936 else
937 {
938 p_warn("Unexpected tag 'arglist' found");
939 }
940 }
941
942 void endTitle()
943 {
944 switch (m_state)
945 {
946 case InGroup:
947 {
948 TagGroupInfo *info = m_curCompound.getGroupInfo();
949 if (info) info->title = m_curString;
950 }
951 break;
952 case InPage:
953 {
954 TagPageInfo *info = m_curCompound.getPageInfo();
955 if (info) info->title = m_curString;
956 }
957 break;
958 default:
959 p_warn("Unexpected tag 'title' found");
960 break;
961 }
962 }
963
965 {
966 if (m_state==InGroup)
967 {
968 TagGroupInfo *info = m_curCompound.getGroupInfo();
969 if (info) info->subgroupList.push_back(m_curString.str());
970 }
971 else
972 {
973 p_warn("Unexpected tag 'subgroup' found");
974 }
975 }
976
980
982 {
983 }
984
985 void buildMemberList(const std::shared_ptr<Entry> &ce,const std::vector<TagMemberInfo> &members);
986 void addDocAnchors(const std::shared_ptr<Entry> &e,const std::vector<TagAnchorInfo> &l);
987
988
1002 };
1003 private:
1004
1005 //------------------------------------
1006
1007 std::vector< TagCompoundVariant > m_tagFileCompounds;
1009
1013
1019 std::stack<State> m_stateStack;
1020 const XMLLocator *m_locator = nullptr;
1021};
1022
1023//---------------------------------------------------------------------------------------------------------------
1024
1026{
1027 using StartCallback = std::function<void(TagFileParser&,const XMLHandlers::Attributes&)>;
1028 using EndCallback = std::function<void(TagFileParser&)>;
1029
1032};
1033
1035{
1036 return [fn](TagFileParser &parser,const XMLHandlers::Attributes &attr) { (parser.*fn)(attr); };
1037}
1038
1040{
1041 return [fn](TagFileParser &parser) { (parser.*fn)(); };
1042}
1043
1044static const std::map< std::string, ElementCallbacks > g_elementHandlers =
1045{
1046 // name, start element callback, end element callback
1073};
1074
1075//---------------------------------------------------------------------------------------------------------------
1076
1084
1085static const std::map< std::string, CompoundFactory > g_compoundFactory =
1086{
1087 // kind tag state creation function
1098 { "file", { TagFileParser::InFile, []() { return TagCompoundVariant::make<TagFileInfo>(); } } },
1099 { "namespace", { TagFileParser::InNamespace, []() { return TagCompoundVariant::make<TagNamespaceInfo>(); } } },
1100 { "concept", { TagFileParser::InConcept, []() { return TagCompoundVariant::make<TagConceptInfo>(); } } },
1101 { "module", { TagFileParser::InModule, []() { return TagCompoundVariant::make<TagModuleInfo>(); } } },
1102 { "group", { TagFileParser::InGroup, []() { return TagCompoundVariant::make<TagGroupInfo>(); } } },
1103 { "page", { TagFileParser::InPage, []() { return TagCompoundVariant::make<TagPageInfo>(); } } },
1104 { "package", { TagFileParser::InPackage, []() { return TagCompoundVariant::make<TagPackageInfo>(); } } },
1105 { "dir", { TagFileParser::InDir, []() { return TagCompoundVariant::make<TagDirInfo>(); } } }
1106};
1107
1108//---------------------------------------------------------------------------------------------------------------
1109
1111{
1112 //printf("startElement '%s'\n",qPrint(name));
1113 auto it = g_elementHandlers.find(name.str());
1114 if (it!=std::end(g_elementHandlers))
1115 {
1116 it->second.startCb(*this,attrib);
1117 }
1118 else
1119 {
1120 p_warn("Unknown start tag '{}' found!",name);
1121 }
1122}
1123
1125{
1126 //printf("endElement '%s'\n",qPrint(name));
1127 auto it = g_elementHandlers.find(name.str());
1128 if (it!=std::end(g_elementHandlers))
1129 {
1130 it->second.endCb(*this);
1131 }
1132 else
1133 {
1134 p_warn("Unknown end tag '{}' found!",name);
1135 }
1136}
1137
1139{
1140 m_curString = "";
1141 std::string kind = XMLHandlers::value(attrib,"kind");
1142 std::string isObjC = XMLHandlers::value(attrib,"objc");
1143
1144 auto it = g_compoundFactory.find(kind);
1145 if (it!=g_compoundFactory.end())
1146 {
1147 m_curCompound = it->second.make_instance();
1148 m_state = it->second.state;
1149 TagCompoundInfo *info = m_curCompound.getCompoundInfo();
1150 if (info) info->lineNr = m_locator->lineNr();
1151 }
1152 else
1153 {
1154 p_warn("Unknown compound attribute '{}' found!",kind);
1155 m_state = Invalid;
1156 }
1157
1158 TagClassInfo *classInfo = m_curCompound.getClassInfo();
1159 if (isObjC=="yes" && classInfo)
1160 {
1161 classInfo->isObjC = TRUE;
1162 }
1163}
1164
1165/*! Dumps the internal structures. For debugging only! */
1167{
1168 Debug::print(Debug::Tag,0,"-------- Results --------\n");
1169 //============== CLASSES
1170 for (const auto &comp : m_tagFileCompounds)
1171 {
1172 if (comp.type()==TagCompoundVariant::Type::Class)
1173 {
1174 const TagClassInfo *cd = comp.getClassInfo();
1175 Debug::print(Debug::Tag,0,"class '{}'\n",cd->name);
1176 Debug::print(Debug::Tag,0," filename '{}'\n",cd->filename);
1177 for (const BaseInfo &bi : cd->bases)
1178 {
1179 Debug::print(Debug::Tag,0, " base: {}\n",bi.name);
1180 }
1181
1182 for (const auto &md : cd->members)
1183 {
1184 Debug::print(Debug::Tag,0," member:\n");
1185 Debug::print(Debug::Tag,0," kind: '{}'\n",md.kind);
1186 Debug::print(Debug::Tag,0," name: '{}'\n",md.name);
1187 Debug::print(Debug::Tag,0," anchor: '{}'\n",md.anchor);
1188 Debug::print(Debug::Tag,0," arglist: '{}'\n",md.arglist);
1189 }
1190 }
1191 }
1192 //============== CONCEPTS
1193 for (const auto &comp : m_tagFileCompounds)
1194 {
1195 if (comp.type()==TagCompoundVariant::Type::Concept)
1196 {
1197 const TagConceptInfo *cd = comp.getConceptInfo();
1198
1199 Debug::print(Debug::Tag,0,"concept '{}'\n",cd->name);
1200 Debug::print(Debug::Tag,0," filename '{}'\n",cd->filename);
1201 }
1202 }
1203 //============== MODULES
1204 for (const auto &comp : m_tagFileCompounds)
1205 {
1206 if (comp.type()==TagCompoundVariant::Type::Module)
1207 {
1208 const TagModuleInfo *mi = comp.getModuleInfo();
1209
1210 Debug::print(Debug::Tag,0,"module '{}'\n",mi->name);
1211 Debug::print(Debug::Tag,0," filename '{}'\n",mi->filename);
1212 }
1213 }
1214 //============== NAMESPACES
1215 for (const auto &comp : m_tagFileCompounds)
1216 {
1217 if (comp.type()==TagCompoundVariant::Type::Namespace)
1218 {
1219 const TagNamespaceInfo *nd = comp.getNamespaceInfo();
1220
1221 Debug::print(Debug::Tag,0,"namespace '{}'\n",nd->name);
1222 Debug::print(Debug::Tag,0," filename '{}'\n",nd->filename);
1223 for (const auto &cls : nd->classList)
1224 {
1225 Debug::print(Debug::Tag,0, " class: {}\n",cls);
1226 }
1227
1228 for (const auto &md : nd->members)
1229 {
1230 Debug::print(Debug::Tag,0," member:\n");
1231 Debug::print(Debug::Tag,0," kind: '{}'\n",md.kind);
1232 Debug::print(Debug::Tag,0," name: '{}'\n",md.name);
1233 Debug::print(Debug::Tag,0," anchor: '{}'\n",md.anchor);
1234 Debug::print(Debug::Tag,0," arglist: '{}'\n",md.arglist);
1235 }
1236 }
1237 }
1238
1239 //============== FILES
1240 for (const auto &comp : m_tagFileCompounds)
1241 {
1242 if (comp.type()==TagCompoundVariant::Type::File)
1243 {
1244 const TagFileInfo *fd = comp.getFileInfo();
1245
1246 Debug::print(Debug::Tag,0,"file '{}'\n",fd->name);
1247 Debug::print(Debug::Tag,0," filename '{}'\n",fd->filename);
1248 for (const auto &ns : fd->namespaceList)
1249 {
1250 Debug::print(Debug::Tag,0, " namespace: {}\n",ns);
1251 }
1252 for (const auto &cs : fd->classList)
1253 {
1254 Debug::print(Debug::Tag,0, " class: {} \n",cs);
1255 }
1256
1257 for (const auto &md : fd->members)
1258 {
1259 Debug::print(Debug::Tag,0," member:\n");
1260 Debug::print(Debug::Tag,0," kind: '{}'\n",md.kind);
1261 Debug::print(Debug::Tag,0," name: '{}'\n",md.name);
1262 Debug::print(Debug::Tag,0," anchor: '{}'\n",md.anchor);
1263 Debug::print(Debug::Tag,0," arglist: '{}'\n",md.arglist);
1264 }
1265
1266 for (const auto &ii : fd->includes)
1267 {
1268 Debug::print(Debug::Tag,0," includes id: {} name: {}\n",ii.id,ii.name);
1269 }
1270 }
1271 }
1272
1273 //============== GROUPS
1274 for (const auto &comp : m_tagFileCompounds)
1275 {
1276 if (comp.type()==TagCompoundVariant::Type::Group)
1277 {
1278 const TagGroupInfo *gd = comp.getGroupInfo();
1279 Debug::print(Debug::Tag,0,"group '{}'\n",gd->name);
1280 Debug::print(Debug::Tag,0," filename '{}'\n",gd->filename);
1281
1282 for (const auto &ns : gd->namespaceList)
1283 {
1284 Debug::print(Debug::Tag,0, " namespace: {}\n",ns);
1285 }
1286 for (const auto &cs : gd->classList)
1287 {
1288 Debug::print(Debug::Tag,0, " class: {}\n",cs);
1289 }
1290 for (const auto &fi : gd->fileList)
1291 {
1292 Debug::print(Debug::Tag,0, " file: {}\n",fi);
1293 }
1294 for (const auto &sg : gd->subgroupList)
1295 {
1296 Debug::print(Debug::Tag,0, " subgroup: {}\n",sg);
1297 }
1298 for (const auto &pg : gd->pageList)
1299 {
1300 Debug::print(Debug::Tag,0, " page: {}\n",pg);
1301 }
1302
1303 for (const auto &md : gd->members)
1304 {
1305 Debug::print(Debug::Tag,0," member:\n");
1306 Debug::print(Debug::Tag,0," kind: '{}'\n",md.kind);
1307 Debug::print(Debug::Tag,0," name: '{}'\n",md.name);
1308 Debug::print(Debug::Tag,0," anchor: '{}'\n",md.anchor);
1309 Debug::print(Debug::Tag,0," arglist: '{}'\n",md.arglist);
1310 }
1311 }
1312 }
1313
1314 //============== PAGES
1315 for (const auto &comp : m_tagFileCompounds)
1316 {
1317 if (comp.type()==TagCompoundVariant::Type::Page)
1318 {
1319 const TagPageInfo *pd = comp.getPageInfo();
1320 Debug::print(Debug::Tag,0,"page '{}'\n",pd->name);
1321 Debug::print(Debug::Tag,0," title '{}'\n",pd->title);
1322 Debug::print(Debug::Tag,0," filename '{}'\n",pd->filename);
1323 }
1324 }
1325
1326 //============== DIRS
1327 for (const auto &comp : m_tagFileCompounds)
1328 {
1329 if (comp.type()==TagCompoundVariant::Type::Dir)
1330 {
1331 const TagDirInfo *dd = comp.getDirInfo();
1332 {
1333 Debug::print(Debug::Tag,0,"dir '{}'\n",dd->name);
1334 Debug::print(Debug::Tag,0," path '{}'\n",dd->path);
1335 for (const auto &fi : dd->fileList)
1336 {
1337 Debug::print(Debug::Tag,0, " file: {}\n",fi);
1338 }
1339 for (const auto &sd : dd->subdirList)
1340 {
1341 Debug::print(Debug::Tag,0, " subdir: {}\n",sd);
1342 }
1343 }
1344 }
1345 }
1346 Debug::print(Debug::Tag,0,"-------------------------\n");
1347}
1348
1349void TagFileParser::addDocAnchors(const std::shared_ptr<Entry> &e,const std::vector<TagAnchorInfo> &l)
1350{
1351 for (const auto &ta : l)
1352 {
1353 if (SectionManager::instance().find(QCString(ta.label))==nullptr)
1354 {
1355 //printf("New sectionInfo file=%s anchor=%s\n",
1356 // qPrint(ta->fileName),qPrint(ta->label));
1358 ta.label,ta.fileName,-1,ta.title,
1360 e->anchors.push_back(si);
1361 }
1362 else
1363 {
1364 //printf("Replace sectionInfo file=%s anchor=%s\n",
1365 // qPrint(ta->fileName),qPrint(ta->label));
1367 ta.label,ta.fileName,-1,ta.title,
1369 }
1370 }
1371}
1372
1373void TagFileParser::buildMemberList(const std::shared_ptr<Entry> &ce,const std::vector<TagMemberInfo> &members)
1374{
1375 for (const auto &tmi : members)
1376 {
1377 std::shared_ptr<Entry> me = std::make_shared<Entry>();
1378 me->type = tmi.type;
1379 me->name = tmi.name;
1380 me->args = tmi.arglist;
1381 if (!me->args.isEmpty())
1382 {
1383 me->argList = *stringToArgumentList(SrcLangExt::Cpp,me->args);
1384 }
1385 if (tmi.enumValues.size()>0)
1386 {
1387 me->spec.setStrong(true);
1388 for (const auto &evi : tmi.enumValues)
1389 {
1390 std::shared_ptr<Entry> ev = std::make_shared<Entry>();
1391 ev->type = "@";
1392 ev->name = evi.name;
1393 ev->id = evi.clangid;
1394 ev->section = EntryType::makeVariable();
1395 ev->tagInfoData.tagName = m_tagName;
1396 ev->tagInfoData.anchor = evi.anchor;
1397 ev->tagInfoData.fileName = evi.file;
1398 ev->hasTagInfo = TRUE;
1399 me->moveToSubEntryAndKeep(ev);
1400 }
1401 }
1402 me->protection = tmi.prot;
1403 me->virt = tmi.virt;
1404 me->isStatic = tmi.isStatic;
1405 me->fileName = ce->fileName;
1406 me->id = tmi.clangId;
1407 me->startLine = tmi.lineNr;
1408 if (ce->section.isGroupDoc())
1409 {
1410 me->groups.emplace_back(ce->name,Grouping::GROUPING_INGROUP);
1411 }
1412 addDocAnchors(me,tmi.docAnchors);
1413 me->tagInfoData.tagName = m_tagName;
1414 me->tagInfoData.anchor = tmi.anchor;
1415 me->tagInfoData.fileName = tmi.anchorFile;
1416 me->hasTagInfo = TRUE;
1417 if (tmi.kind=="define")
1418 {
1419 me->type="#define";
1420 me->section = EntryType::makeDefine();
1421 }
1422 else if (tmi.kind=="enumvalue")
1423 {
1424 me->section = EntryType::makeVariable();
1425 me->mtype = MethodTypes::Method;
1426 }
1427 else if (tmi.kind=="property")
1428 {
1429 me->section = EntryType::makeVariable();
1430 me->mtype = MethodTypes::Property;
1431 }
1432 else if (tmi.kind=="event")
1433 {
1434 me->section = EntryType::makeVariable();
1435 me->mtype = MethodTypes::Event;
1436 }
1437 else if (tmi.kind=="variable")
1438 {
1439 me->section = EntryType::makeVariable();
1440 me->mtype = MethodTypes::Method;
1441 }
1442 else if (tmi.kind=="typedef")
1443 {
1444 me->section = EntryType::makeVariable();
1445 me->type.prepend("typedef ");
1446 me->mtype = MethodTypes::Method;
1447 }
1448 else if (tmi.kind=="enumeration")
1449 {
1450 me->section = EntryType::makeEnum();
1451 me->mtype = MethodTypes::Method;
1452 }
1453 else if (tmi.kind=="function")
1454 {
1455 me->section = EntryType::makeFunction();
1456 me->mtype = MethodTypes::Method;
1457 }
1458 else if (tmi.kind=="signal")
1459 {
1460 me->section = EntryType::makeFunction();
1461 me->mtype = MethodTypes::Signal;
1462 }
1463 else if (tmi.kind=="prototype")
1464 {
1465 me->section = EntryType::makeFunction();
1466 me->mtype = MethodTypes::Method;
1467 }
1468 else if (tmi.kind=="friend")
1469 {
1470 me->section = EntryType::makeFunction();
1471 me->type.prepend("friend ");
1472 me->mtype = MethodTypes::Method;
1473 }
1474 else if (tmi.kind=="dcop")
1475 {
1476 me->section = EntryType::makeFunction();
1477 me->mtype = MethodTypes::DCOP;
1478 }
1479 else if (tmi.kind=="slot")
1480 {
1481 me->section = EntryType::makeFunction();
1482 me->mtype = MethodTypes::Slot;
1483 }
1484 ce->moveToSubEntryAndKeep(me);
1485 }
1486}
1487
1488/*! Injects the info gathered by the XML parser into the Entry tree.
1489 * This tree contains the information extracted from the input in a
1490 * "unrelated" form.
1491 */
1492void TagFileParser::buildLists(const std::shared_ptr<Entry> &root)
1493{
1494 // build class list
1495 for (const auto &comp : m_tagFileCompounds)
1496 {
1497 const TagClassInfo *tci = comp.getClassInfo();
1498 if (tci)
1499 {
1500 std::shared_ptr<Entry> ce = std::make_shared<Entry>();
1501 ce->section = EntryType::makeClass();
1502 switch (tci->kind)
1503 {
1504 case TagClassInfo::Kind::Class: break;
1505 case TagClassInfo::Kind::Struct: ce->spec = TypeSpecifier().setStruct(true); break;
1506 case TagClassInfo::Kind::Union: ce->spec = TypeSpecifier().setUnion(true); break;
1507 case TagClassInfo::Kind::Interface: ce->spec = TypeSpecifier().setInterface(true); break;
1508 case TagClassInfo::Kind::Enum: ce->spec = TypeSpecifier().setEnum(true); break;
1509 case TagClassInfo::Kind::Exception: ce->spec = TypeSpecifier().setException(true); break;
1510 case TagClassInfo::Kind::Protocol: ce->spec = TypeSpecifier().setProtocol(true); break;
1511 case TagClassInfo::Kind::Category: ce->spec = TypeSpecifier().setCategory(true); break;
1512 case TagClassInfo::Kind::Service: ce->spec = TypeSpecifier().setService(true); break;
1513 case TagClassInfo::Kind::Singleton: ce->spec = TypeSpecifier().setSingleton(true); break;
1514 case TagClassInfo::Kind::None: // should never happen, means not properly initialized
1515 assert(tci->kind != TagClassInfo::Kind::None);
1516 break;
1517 }
1518 ce->name = tci->name;
1520 {
1521 ce->name+="-p";
1522 }
1523 addDocAnchors(ce,tci->docAnchors);
1524 ce->tagInfoData.tagName = m_tagName;
1525 ce->tagInfoData.anchor = tci->anchor;
1526 ce->tagInfoData.fileName = tci->filename;
1527 ce->startLine = tci->lineNr;
1528 ce->fileName = m_tagName;
1529 ce->hasTagInfo = TRUE;
1530 ce->id = tci->clangId;
1531 ce->lang = tci->isObjC ? SrcLangExt::ObjC : SrcLangExt::Unknown;
1532 // transfer base class list
1533 ce->extends = tci->bases;
1534 if (!tci->templateArguments.empty())
1535 {
1536 ArgumentList al;
1537 for (const auto &argName : tci->templateArguments)
1538 {
1539 Argument a;
1540 a.type = "class";
1541 a.name = argName.c_str();
1542 al.push_back(a);
1543 }
1544 ce->tArgLists.push_back(al);
1545 }
1546
1547 buildMemberList(ce,tci->members);
1548 root->moveToSubEntryAndKeep(ce);
1549 }
1550 }
1551
1552 // build file list
1553 for (const auto &comp : m_tagFileCompounds)
1554 {
1555 const TagFileInfo *tfi = comp.getFileInfo();
1556 if (tfi)
1557 {
1558 std::shared_ptr<Entry> fe = std::make_shared<Entry>();
1559 fe->section = guessSection(tfi->name);
1560 fe->name = tfi->name;
1561 addDocAnchors(fe,tfi->docAnchors);
1562 fe->tagInfoData.tagName = m_tagName;
1563 fe->tagInfoData.fileName = tfi->filename;
1564 fe->hasTagInfo = TRUE;
1565
1566 QCString fullName = m_tagName+":"+tfi->path+stripPath(tfi->name);
1567 fe->fileName = fullName;
1568 fe->startLine = tfi->lineNr;
1569 //printf("createFileDef() filename=%s\n",qPrint(tfi->filename));
1570 QCString tagid = m_tagName+":"+tfi->path;
1571 auto fd = createFileDef(tagid, tfi->name,m_tagName, tfi->filename);
1572 FileName *mn = Doxygen::inputNameLinkedMap->find(tfi->name);
1573 if (mn)
1574 {
1575 mn->push_back(std::move(fd));
1576 }
1577 else
1578 {
1579 mn = Doxygen::inputNameLinkedMap->add(tfi->name,fullName);
1580 mn->push_back(std::move(fd));
1581 }
1582 buildMemberList(fe,tfi->members);
1583 root->moveToSubEntryAndKeep(fe);
1584 }
1585 }
1586
1587 // build concept list
1588 for (const auto &comp : m_tagFileCompounds)
1589 {
1590 const TagConceptInfo *tci = comp.getConceptInfo();
1591 if (tci)
1592 {
1593 std::shared_ptr<Entry> ce = std::make_shared<Entry>();
1594 ce->section = EntryType::makeConcept();
1595 ce->name = tci->name;
1596 addDocAnchors(ce,tci->docAnchors);
1597 ce->tagInfoData.tagName = m_tagName;
1598 ce->tagInfoData.fileName = tci->filename;
1599 ce->startLine = tci->lineNr;
1600 ce->fileName = m_tagName;
1601 ce->hasTagInfo = TRUE;
1602 ce->id = tci->clangId;
1603
1604 root->moveToSubEntryAndKeep(ce);
1605 }
1606 }
1607
1608 // build module list
1609 for (const auto &comp : m_tagFileCompounds)
1610 {
1611 const TagModuleInfo *tmi = comp.getModuleInfo();
1612 if (tmi)
1613 {
1614 auto &mm = ModuleManager::instance();
1615 mm.createModuleDef(tmi->filename,tmi->lineNr,1,true,tmi->name,QCString());
1616 mm.addTagInfo(tmi->filename,m_tagName,tmi->clangId);
1617
1618 ModuleDef *mod = mm.getPrimaryInterface(tmi->name);
1619 if (mod && !tmi->docAnchors.empty())
1620 {
1621 std::vector<const SectionInfo *> anchorList;
1622 for (const auto &ta : tmi->docAnchors)
1623 {
1624 if (SectionManager::instance().find(QCString(ta.label))==nullptr)
1625 {
1626 //printf("New sectionInfo file=%s anchor=%s\n",
1627 // qPrint(ta->fileName),qPrint(ta->label));
1629 ta.label,ta.fileName,-1,ta.title,
1631 anchorList.push_back(si);
1632 }
1633 else
1634 {
1635 p_warn("Duplicate anchor {} found",ta.label);
1636 }
1637 }
1638 mod->addSectionsToDefinition(anchorList);
1639 }
1640 }
1641 }
1642
1643
1644 // build namespace list
1645 for (const auto &comp : m_tagFileCompounds)
1646 {
1647 const TagNamespaceInfo *tni = comp.getNamespaceInfo();
1648 if (tni)
1649 {
1650 std::shared_ptr<Entry> ne = std::make_shared<Entry>();
1651 ne->section = EntryType::makeNamespace();
1652 ne->name = tni->name;
1653 addDocAnchors(ne,tni->docAnchors);
1654 ne->tagInfoData.tagName = m_tagName;
1655 ne->tagInfoData.fileName = tni->filename;
1656 ne->startLine = tni->lineNr;
1657 ne->fileName = m_tagName;
1658 ne->hasTagInfo = TRUE;
1659 ne->id = tni->clangId;
1660
1661 buildMemberList(ne,tni->members);
1662 root->moveToSubEntryAndKeep(ne);
1663 }
1664 }
1665
1666 // build package list
1667 for (const auto &comp : m_tagFileCompounds)
1668 {
1669 const TagPackageInfo *tpgi = comp.getPackageInfo();
1670 if (tpgi)
1671 {
1672 std::shared_ptr<Entry> pe = std::make_shared<Entry>();
1673 pe->section = EntryType::makePackage();
1674 pe->name = tpgi->name;
1675 addDocAnchors(pe,tpgi->docAnchors);
1676 pe->tagInfoData.tagName = m_tagName;
1677 pe->tagInfoData.fileName = tpgi->filename;
1678 pe->startLine = tpgi->lineNr;
1679 pe->fileName = m_tagName;
1680 pe->hasTagInfo = TRUE;
1681
1682 buildMemberList(pe,tpgi->members);
1683 root->moveToSubEntryAndKeep(pe);
1684 }
1685 }
1686
1687 // build group list
1688 for (const auto &comp : m_tagFileCompounds)
1689 {
1690 const TagGroupInfo *tgi = comp.getGroupInfo();
1691 if (tgi)
1692 {
1693 std::shared_ptr<Entry> ge = std::make_shared<Entry>();
1694 ge->section = EntryType::makeGroupDoc();
1695 ge->name = tgi->name;
1696 ge->type = tgi->title;
1697 addDocAnchors(ge,tgi->docAnchors);
1698 ge->tagInfoData.tagName = m_tagName;
1699 ge->tagInfoData.fileName = tgi->filename;
1700 ge->startLine = tgi->lineNr;
1701 ge->fileName = m_tagName;
1702 ge->hasTagInfo = TRUE;
1703
1704 buildMemberList(ge,tgi->members);
1705 root->moveToSubEntryAndKeep(ge);
1706 }
1707 }
1708
1709 for (const auto &comp : m_tagFileCompounds)
1710 {
1711 const TagGroupInfo *tgi = comp.getGroupInfo();
1712 if (tgi)
1713 {
1714 // set subgroup relations bug_774118
1715 for (const auto &sg : tgi->subgroupList)
1716 {
1717 const auto &children = root->children();
1718 auto i = std::find_if(children.begin(),children.end(),
1719 [&](const std::shared_ptr<Entry> &e) { return e->name == sg.c_str(); });
1720 if (i!=children.end())
1721 {
1722 (*i)->groups.emplace_back(tgi->name,Grouping::GROUPING_INGROUP);
1723 }
1724 }
1725 }
1726 }
1727
1728 // build page list
1729 for (const auto &comp : m_tagFileCompounds)
1730 {
1731 const TagPageInfo *tpi = comp.getPageInfo();
1732 if (tpi)
1733 {
1734 std::shared_ptr<Entry> pe = std::make_shared<Entry>();
1735 bool isIndex = (stripExtensionGeneral(tpi->filename,getFileNameExtension(tpi->filename))=="index");
1736 pe->section = isIndex ? EntryType::makeMainpageDoc() : EntryType::makePageDoc();
1737 pe->name = tpi->name;
1738 pe->args = tpi->title;
1739 for (const auto &subpage : tpi->subpages)
1740 {
1741 // we add subpage labels as a kind of "inheritance" relation to prevent
1742 // needing to add another list to the Entry class.
1743 pe->extends.emplace_back(stripExtension(QCString(subpage)),Protection::Public,Specifier::Normal);
1744 }
1745 addDocAnchors(pe,tpi->docAnchors);
1746 pe->tagInfoData.tagName = m_tagName;
1747 pe->tagInfoData.fileName = stripExtension(tpi->filename);
1748 pe->startLine = tpi->lineNr;
1749 pe->fileName = m_tagName;
1750 pe->hasTagInfo = TRUE;
1751 root->moveToSubEntryAndKeep(pe);
1752 }
1753 }
1754}
1755
1757{
1758 for (const auto &comp : m_tagFileCompounds)
1759 {
1760 const TagFileInfo *tfi = comp.getFileInfo();
1761 if (tfi)
1762 {
1763 //printf("tag file tagName=%s path=%s name=%s\n",qPrint(m_tagName),qPrint(tfi->path),qPrint(tfi->name));
1764 FileName *fn = Doxygen::inputNameLinkedMap->find(tfi->name);
1765 if (fn)
1766 {
1767 for (const auto &fd : *fn)
1768 {
1769 //printf("input file path=%s name=%s\n",qPrint(fd->getPath()),qPrint(fd->name()));
1770 if (fd->getPath()==QCString(m_tagName+":"+tfi->path))
1771 {
1772 //printf("found\n");
1773 for (const auto &ii : tfi->includes)
1774 {
1775 //printf("ii->name='%s'\n",qPrint(ii->name));
1776 FileName *ifn = Doxygen::inputNameLinkedMap->find(ii.name);
1777 ASSERT(ifn!=nullptr);
1778 if (ifn)
1779 {
1780 for (const auto &ifd : *ifn)
1781 {
1782 //printf("ifd->getOutputFileBase()=%s ii->id=%s\n",
1783 // qPrint(ifd->getOutputFileBase()),qPrint(ii->id));
1784 if (ifd->getOutputFileBase()==QCString(ii.id))
1785 {
1787 if (ii.isModule)
1788 {
1790 }
1791 else if (ii.isImported)
1792 {
1794 }
1795 else if (ii.isLocal)
1796 {
1798 }
1799 fd->addIncludeDependency(ifd.get(),ii.text,kind);
1800 }
1801 }
1802 }
1803 }
1804 }
1805 }
1806 }
1807 }
1808 }
1809}
1810
1811} // namespace
1812
1813// ----------------- public part -----------------------------------------------
1814
1815void parseTagFile(const std::shared_ptr<Entry> &root,const char *fullName)
1816{
1817 TagFileParser tagFileParser(fullName);
1818 QCString inputStr = fileToString(fullName);
1819 XMLHandlers handlers;
1820 // connect the generic events handlers of the XML parser to the specific handlers of the tagFileParser object
1821 handlers.startDocument = [&tagFileParser]() { tagFileParser.startDocument(); };
1822 handlers.startElement = [&tagFileParser](const std::string &name,const XMLHandlers::Attributes &attrs) { tagFileParser.startElement(QCString(name),attrs); };
1823 handlers.endElement = [&tagFileParser](const std::string &name) { tagFileParser.endElement(QCString(name)); };
1824 handlers.characters = [&tagFileParser](const std::string &chars) { tagFileParser.characters(QCString(chars)); };
1825 handlers.error = [&tagFileParser](const std::string &fileName,int lineNr,const std::string &msg) { tagFileParser.error(QCString(fileName),lineNr,QCString(msg)); };
1826 XMLParser parser(handlers);
1827 tagFileParser.setDocumentLocator(&parser);
1828 parser.parse(fullName,inputStr.data(),Debug::isFlagSet(Debug::Lex_xml),
1829 [&]() { DebugLex::print(Debug::Lex_xml,"Entering","libxml/xml.l",fullName); },
1830 [&]() { DebugLex::print(Debug::Lex_xml,"Finished", "libxml/xml.l",fullName); }
1831 );
1832 tagFileParser.buildLists(root);
1833 tagFileParser.addIncludes();
1835 {
1836 tagFileParser.dump();
1837 }
1838}
static bool looksGenerated(const std::string &anchor)
Returns true if anchor is a potentially generated anchor.
Definition anchor.cpp:140
This class represents an function or template argument list.
Definition arguments.h:60
void push_back(const Argument &a)
Definition arguments.h:95
@ Tag
Definition debug.h:45
@ Lex_xml
Definition debug.h:70
static bool isFlagSet(const DebugMask mask)
Definition debug.cpp:132
static void print(DebugMask mask, int prio, fmt::format_string< Args... > fmt, Args &&... args)
Definition debug.h:76
virtual void addSectionsToDefinition(const std::vector< const SectionInfo * > &anchorList)=0
static FileNameLinkedMap * inputNameLinkedMap
Definition doxygen.h:105
Class representing all files with a certain base name.
Definition filename.h:30
static ModuleManager & instance()
This is an alternative implementation of QCString.
Definition qcstring.h:101
QCString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
Definition qcstring.h:245
const std::string & str() const
Definition qcstring.h:537
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string.
Definition qcstring.h:159
class that provide information about a section.
Definition section.h:57
SectionInfo * replace(const QCString &label, const QCString &fileName, int lineNr, const QCString &title, SectionType type, int level, const QCString &ref=QCString())
Definition section.h:154
SectionInfo * add(const SectionInfo &si)
Definition section.h:138
static SectionManager & instance()
returns a reference to the singleton
Definition section.h:175
static constexpr int Anchor
Definition section.h:40
Wrapper class for a number of boolean properties.
Definition types.h:492
Event handlers that can installed by the client and called while parsing a XML document.
Definition xml.h:27
std::unordered_map< std::string, std::string > Attributes
Definition xml.h:29
std::function< EndElementType > endElement
handler invoked when a closing tag has been found
Definition xml.h:40
std::function< StartElementType > startElement
handler invoked when an opening tag has been found
Definition xml.h:39
std::function< CharsType > characters
handler invoked when content between tags has been found
Definition xml.h:41
static std::string value(const Attributes &attrib, const std::string &key)
Definition xml.h:44
std::function< ErrorType > error
handler invoked when the parser encounters an error
Definition xml.h:42
std::function< StartDocType > startDocument
handler invoked at the start of the document
Definition xml.h:37
void parse(const char *fileName, const char *inputString, bool debugEnabled, std::function< void()> debugStart, std::function< void()> debugEnd, std::function< Transcode > transcoder=[](std::string &s, const char *){ return true;})
Definition xml.l:447
TagAnchorInfo(const QCString &f, const QCString &l, const QCString &t=QCString())
Definition tagreader.cpp:51
Variant class that holds a unique pointer to one of the specific container types.
const R * get() const
Generic const getter.
std::variant< std::monostate, TagClassInfoPtr, TagConceptInfoPtr, TagNamespaceInfoPtr, TagPackageInfoPtr, TagFileInfoPtr, TagGroupInfoPtr, TagPageInfoPtr, TagDirInfoPtr, TagModuleInfoPtr > VariantT
TagCompoundVariant(const TagCompoundVariant &)=delete
static TagCompoundVariant make(Args &&... args)
Generic factory method to create a variant holding a unique pointer to a given compound type.
TagCompoundVariant & operator=(const TagCompoundVariant &)=delete
const TagNamespaceInfo * getNamespaceInfo() const
TagCompoundInfo * getCompoundInfo()
Convenience method to get the shared compound info.
TagCompoundVariant & operator=(TagCompoundVariant &&)=default
Container for enum values that are scoped within an enum.
Definition tagreader.cpp:62
void addDocAnchors(const std::shared_ptr< Entry > &e, const std::vector< TagAnchorInfo > &l)
void startIncludes(const XMLHandlers::Attributes &attrib)
void startDocAnchor(const XMLHandlers::Attributes &attrib)
void startElement(const QCString &name, const XMLHandlers::Attributes &attrib)
void startStringValue(const XMLHandlers::Attributes &)
void setDocumentLocator(const XMLLocator *locator)
void startBase(const XMLHandlers::Attributes &attrib)
void error(const QCString &fileName, int lineNr, const QCString &msg)
void startIgnoreElement(const XMLHandlers::Attributes &)
void buildLists(const std::shared_ptr< Entry > &root)
void startMember(const XMLHandlers::Attributes &attrib)
void buildMemberList(const std::shared_ptr< Entry > &ce, const std::vector< TagMemberInfo > &members)
void startCompound(const XMLHandlers::Attributes &attrib)
std::vector< TagCompoundVariant > m_tagFileCompounds
void startEnumValue(const XMLHandlers::Attributes &attrib)
Container for include info that can be read from a tagfile.
Definition tagreader.cpp:72
Container for member specific info that can be read from a tagfile.
Definition tagreader.cpp:85
std::vector< TagEnumValueInfo > enumValues
Definition tagreader.cpp:98
std::vector< std::string > StringVector
Definition containers.h:33
std::unique_ptr< ArgumentList > stringToArgumentList(SrcLangExt lang, const QCString &argsString, QCString *extraTypeChars=nullptr)
Definition defargs.l:814
std::unique_ptr< FileDef > createFileDef(const QCString &p, const QCString &n, const QCString &ref, const QCString &dn)
Definition filedef.cpp:267
IncludeKind
Definition filedef.h:47
@ ImportLocal
Definition filedef.h:54
@ ImportModule
Definition filedef.h:55
@ IncludeLocal
Definition filedef.h:50
@ IncludeSystem
Definition filedef.h:49
@ ImportSystem
Definition filedef.h:53
#define warn(file, line, fmt,...)
Definition message.h:97
#define msg(fmt,...)
Definition message.h:94
std::unique_ptr< TagPackageInfo > TagPackageInfoPtr
std::unique_ptr< TagFileInfo > TagFileInfoPtr
std::unique_ptr< TagClassInfo > TagClassInfoPtr
std::unique_ptr< TagNamespaceInfo > TagNamespaceInfoPtr
std::unique_ptr< TagDirInfo > TagDirInfoPtr
static const std::map< std::string, CompoundFactory > g_compoundFactory
std::unique_ptr< TagConceptInfo > TagConceptInfoPtr
std::unique_ptr< TagModuleInfo > TagModuleInfoPtr
std::unique_ptr< TagPageInfo > TagPageInfoPtr
ElementCallbacks::EndCallback endCb(void(TagFileParser::*fn)())
static const std::map< std::string, ElementCallbacks > g_elementHandlers
ElementCallbacks::StartCallback startCb(void(TagFileParser::*fn)(const XMLHandlers::Attributes &))
std::unique_ptr< TagGroupInfo > TagGroupInfoPtr
#define TRUE
Definition qcstring.h:37
#define ASSERT(x)
Definition qcstring.h:39
This class contains the information about the argument of a function or template.
Definition arguments.h:27
QCString type
Definition arguments.h:37
QCString name
Definition arguments.h:39
This class stores information about an inheritance relation.
Definition entry.h:90
QCString name
the name of the base class
Definition entry.h:94
@ GROUPING_INGROUP
membership in group was defined by @ingroup
Definition types.h:74
CompoundFactory(TagFileParser::State s, const CreateFunc &f)
std::function< TagCompoundVariant()> CreateFunc
std::function< void(TagFileParser &, const XMLHandlers::Attributes &)> StartCallback
std::function< void(TagFileParser &)> EndCallback
Container for class specific info that can be read from a tagfile.
Container for concept specific info that can be read from a tagfile.
Container for directory specific info that can be read from a tagfile.
Container for file specific info that can be read from a tagfile.
Container for group specific info that can be read from a tagfile.
Container for module specific info that can be read from a tagfile.
Container for namespace specific info that can be read from a tagfile.
Container for package specific info that can be read from a tagfile.
Container for page specific info that can be read from a tagfile.
void parseTagFile(const std::shared_ptr< Entry > &root, const char *fullName)
#define p_warn(fmt,...)
@ Property
Definition types.h:32
Protection
Protection level of members.
Definition types.h:26
@ Public
Definition types.h:26
@ Private
Definition types.h:26
@ Protected
Definition types.h:26
@ Unknown
Definition types.h:43
Specifier
Virtualness of a member.
Definition types.h:29
@ Virtual
Definition types.h:29
@ Normal
Definition types.h:29
@ Pure
Definition types.h:29
QCString stripPath(const QCString &s)
Definition util.cpp:5388
QCString fileToString(const QCString &name, bool filter, bool isSourceCode)
Definition util.cpp:1414
QCString stripExtensionGeneral(const QCString &fName, const QCString &ext)
Definition util.cpp:5351
QCString stripExtension(const QCString &fName)
Definition util.cpp:5361
EntryType guessSection(const QCString &name)
Definition util.cpp:349
QCString getFileNameExtension(const QCString &fn)
Definition util.cpp:5687
A bunch of utility functions.