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 public:
331 explicit TagFileParser(const char *tagName) : m_tagName(tagName) {}
332
333 void setDocumentLocator ( const XMLLocator * locator )
334 {
335 m_locator = locator;
336 }
337
339 {
341 }
342
343 void startElement( const QCString &name, const XMLHandlers::Attributes& attrib );
344 void endElement( const QCString &name );
345 void characters ( const QCString & ch ) { m_curString+=ch; }
346 void error( const QCString &fileName,int lineNr,const QCString &msg)
347 {
348 ::warn_(fileName,lineNr,"%s",qPrint(msg));
349 }
350
351 void dump();
352 void buildLists(const std::shared_ptr<Entry> &root);
353 void addIncludes();
354 void startCompound( const XMLHandlers::Attributes& attrib );
355
357 {
358 switch (m_state)
359 {
360 case InClass:
361 case InConcept:
362 case InFile:
363 case InNamespace:
364 case InGroup:
365 case InPage:
366 case InDir:
367 case InModule:
368 case InPackage:
369 m_tagFileCompounds.push_back(std::move(m_curCompound));
370 break;
371 default:
372 p_warn("tag 'compound' was not expected!");
373 break;
374 }
375 }
376
378 {
380 m_curMember.kind = XMLHandlers::value(attrib,"kind");
381 QCString protStr = XMLHandlers::value(attrib,"protection");
382 QCString virtStr = XMLHandlers::value(attrib,"virtualness");
383 QCString staticStr = XMLHandlers::value(attrib,"static");
384 m_curMember.lineNr = m_locator->lineNr();
385 if (protStr=="protected")
386 {
388 }
389 else if (protStr=="private")
390 {
392 }
393 if (virtStr=="virtual")
394 {
396 }
397 else if (virtStr=="pure")
398 {
400 }
401 if (staticStr=="yes")
402 {
403 m_curMember.isStatic = TRUE;
404 }
405 m_stateStack.push(m_state);
407 }
408
410 {
411 m_state = m_stateStack.top();
412 m_stateStack.pop();
413 switch(m_state)
414 {
415 case InClass:
416 case InFile:
417 case InNamespace:
418 case InGroup:
419 case InPackage:
420 {
421 TagCompoundInfo *info = m_curCompound.getCompoundInfo();
422 if (info)
423 {
424 info->members.push_back(m_curMember);
425 }
426 }
427 break;
428 default:
429 p_warn("Unexpected tag 'member' found");
430 break;
431 }
432 }
433
435 {
436 if (m_state==InMember)
437 {
438 m_curString = "";
440 m_curEnumValue.file = XMLHandlers::value(attrib,"file");
441 m_curEnumValue.anchor = XMLHandlers::value(attrib,"anchor");
442 m_curEnumValue.clangid = XMLHandlers::value(attrib,"clangid");
443 m_stateStack.push(m_state);
445 }
446 else
447 {
448 p_warn("Found 'enumvalue' tag outside of member tag");
449 }
450 }
451
453 {
455 m_state = m_stateStack.top();
456 m_stateStack.pop();
457 if (m_state==InMember)
458 {
459 m_curMember.enumValues.push_back(m_curEnumValue);
461 }
462 }
463
465 {
466 // Check whether or not the tag is automatically generate, in that case ignore the tag.
467 switch(m_state)
468 {
469 case InClass:
470 case InConcept:
471 case InFile:
472 case InNamespace:
473 case InGroup:
474 case InPage:
475 case InMember:
476 case InPackage:
477 case InDir:
478 case InModule:
480 break;
481 default:
482 p_warn("Unexpected tag 'docanchor' found");
483 return;
484 }
485 switch(m_state)
486 {
487 case InClass:
488 case InConcept:
489 case InFile:
490 case InNamespace:
491 case InGroup:
492 case InPage:
493 case InPackage:
494 case InDir:
495 case InModule:
496 {
497 TagCompoundInfo *info = m_curCompound.getCompoundInfo();
498 if (info)
499 {
500 info->docAnchors.emplace_back(m_fileName,m_curString,m_title);
501 }
502 }
503 break;
504 case InMember:
505 m_curMember.docAnchors.emplace_back(m_fileName,m_curString,m_title);
506 break;
507 default: break; // will not be reached
508 }
509 }
510
511 void endClass()
512 {
513 switch(m_state)
514 {
515 case InClass:
516 {
517 TagClassInfo *info = m_curCompound.getClassInfo();
518 if (info) info->classList.push_back(m_curString.str());
519 }
520 break;
521 case InFile:
522 {
523 TagFileInfo *info = m_curCompound.getFileInfo();
524 if (info) info->classList.push_back(m_curString.str());
525 }
526 break;
527 case InNamespace:
528 {
529 TagNamespaceInfo *info = m_curCompound.getNamespaceInfo();
530 if (info) info->classList.push_back(m_curString.str());
531 }
532 break;
533 case InGroup:
534 {
535 TagGroupInfo *info = m_curCompound.getGroupInfo();
536 if (info) info->classList.push_back(m_curString.str());
537 }
538 break;
539 case InPackage:
540 {
541 TagPackageInfo *info = m_curCompound.getPackageInfo();
542 if (info) info->classList.push_back(m_curString.str());
543 }
544 break;
545 default:
546 p_warn("Unexpected tag 'class' found");
547 break;
548 }
549 }
550
552 {
553 switch(m_state)
554 {
555 case InNamespace:
556 {
557 TagNamespaceInfo *info = m_curCompound.getNamespaceInfo();
558 if (info) info->conceptList.push_back(m_curString.str());
559 }
560 break;
561 case InFile:
562 {
563 TagFileInfo *info = m_curCompound.getFileInfo();
564 if (info) info->conceptList.push_back(m_curString.str());
565 }
566 break;
567 case InGroup:
568 {
569 TagGroupInfo *info = m_curCompound.getGroupInfo();
570 if (info) info->conceptList.push_back(m_curString.str());
571 }
572 break;
573 default:
574 p_warn("Unexpected tag 'concept' found");
575 break;
576 }
577 }
578
580 {
581 switch(m_state)
582 {
583 case InGroup:
584 {
585 TagGroupInfo *info = m_curCompound.getGroupInfo();
586 if (info) info->moduleList.push_back(m_curString.str());
587 }
588 break;
589 default:
590 p_warn("Unexpected tag 'module' found");
591 break;
592 }
593 }
594
596 {
597 switch(m_state)
598 {
599 case InNamespace:
600 {
601 TagNamespaceInfo *info = m_curCompound.getNamespaceInfo();
602 if (info) info->namespaceList.push_back(m_curString.str());
603 }
604 break;
605 case InFile:
606 {
607 TagFileInfo *info = m_curCompound.getFileInfo();
608 if (info) info->namespaceList.push_back(m_curString.str());
609 }
610 break;
611 case InGroup:
612 {
613 TagGroupInfo *info = m_curCompound.getGroupInfo();
614 if (info) info->namespaceList.push_back(m_curString.str());
615 }
616 break;
617 default:
618 p_warn("Unexpected tag 'namespace' found");
619 break;
620 }
621 }
622
623 void endFile()
624 {
625 switch(m_state)
626 {
627 case InGroup:
628 {
629 TagGroupInfo *info = m_curCompound.getGroupInfo();
630 if (info) info->fileList.push_back(m_curString.str());
631 }
632 break;
633 case InDir:
634 {
635 TagDirInfo *info = m_curCompound.getDirInfo();
636 if (info) info->fileList.push_back(m_curString.str());
637 }
638 break;
639 default:
640 p_warn("Unexpected tag 'file' found");
641 break;
642 }
643 }
644
645 void endPage()
646 {
647 switch(m_state)
648 {
649 case InGroup:
650 {
651 TagGroupInfo *info = m_curCompound.getGroupInfo();
652 if (info) info->fileList.push_back(m_curString.str());
653 }
654 break;
655 default:
656 p_warn("Unexpected tag 'page' found");
657 break;
658 }
659 }
660
662 {
663 switch(m_state)
664 {
665 case InPage:
666 {
667 TagPageInfo *info = m_curCompound.getPageInfo();
668 if (info) info->subpages.push_back(m_curString.str());
669 }
670 break;
671 default:
672 p_warn("Unexpected tag 'subpage' found");
673 break;
674 }
675 }
676
677 void endDir()
678 {
679 switch(m_state)
680 {
681 case InDir:
682 {
683 TagDirInfo *info = m_curCompound.getDirInfo();
684 if (info) info->subdirList.push_back(m_curString.str());
685 }
686 break;
687 default:
688 p_warn("Unexpected tag 'dir' found");
689 break;
690 }
691 }
692
694 {
695 m_curString = "";
696 }
697
699 {
700 m_fileName = XMLHandlers::value(attrib,"file");
701 m_title = XMLHandlers::value(attrib,"title");
702 m_curString = "";
703 }
704
705 void endType()
706 {
707 if (m_state==InMember)
708 {
710 }
711 else
712 {
713 p_warn("Unexpected tag 'type' found");
714 }
715 }
716
717 void endName()
718 {
719 switch (m_state)
720 {
721 case InClass:
722 case InConcept:
723 case InFile:
724 case InNamespace:
725 case InGroup:
726 case InPage:
727 case InDir:
728 case InPackage:
729 case InModule:
730 {
731 TagCompoundInfo *info = m_curCompound.getCompoundInfo();
732 if (info) info->name = m_curString;
733 }
734 break;
735 case InMember:
737 break;
738 default:
739 p_warn("Unexpected tag 'name' found");
740 break;
741 }
742 }
743
745 {
746 m_curString="";
747 TagClassInfo *info = m_curCompound.getClassInfo();
748 if (m_state==InClass && info)
749 {
750 QCString protStr = XMLHandlers::value(attrib,"protection");
751 QCString virtStr = XMLHandlers::value(attrib,"virtualness");
754 if (protStr=="protected")
755 {
757 }
758 else if (protStr=="private")
759 {
760 prot = Protection::Private;
761 }
762 if (virtStr=="virtual")
763 {
764 virt = Specifier::Virtual;
765 }
766 info->bases.emplace_back(m_curString,prot,virt);
767 }
768 else
769 {
770 p_warn("Unexpected tag 'base' found");
771 }
772 }
773
774 void endBase()
775 {
776 TagClassInfo *info = m_curCompound.getClassInfo();
777 if (m_state==InClass && info)
778 {
779 info->bases.back().name = m_curString;
780 }
781 else
782 {
783 p_warn("Unexpected tag 'base' found");
784 }
785 }
786
788 {
790 m_curIncludes.id = XMLHandlers::value(attrib,"id");
791 m_curIncludes.name = XMLHandlers::value(attrib,"name");
792 m_curIncludes.isLocal = XMLHandlers::value(attrib,"local")=="yes";
793 m_curIncludes.isImported = XMLHandlers::value(attrib,"imported")=="yes";
794 m_curIncludes.isModule = XMLHandlers::value(attrib,"module")=="yes";
795 m_curIncludes.isObjC = XMLHandlers::value(attrib,"objc")=="yes";
796 m_curString="";
797 }
798
800 {
802 TagFileInfo *info = m_curCompound.getFileInfo();
803 if (m_state==InFile && info)
804 {
805 info->includes.push_back(m_curIncludes);
806 }
807 else
808 {
809 p_warn("Unexpected tag 'includes' found");
810 }
811 }
812
814 {
815 TagClassInfo *info = m_curCompound.getClassInfo();
816 if (m_state==InClass && info)
817 {
818 info->templateArguments.push_back(m_curString.str());
819 }
820 else
821 {
822 p_warn("Unexpected tag 'templarg' found");
823 }
824 }
825
827 {
828 switch (m_state)
829 {
830 case InClass:
831 case InConcept:
832 case InNamespace:
833 case InFile:
834 case InGroup:
835 case InPage:
836 case InPackage:
837 case InDir:
838 case InModule:
839 {
840 TagCompoundInfo *info = m_curCompound.getCompoundInfo();
841 if (info) info->filename = m_curString;
842 }
843 break;
844 default:
845 p_warn("Unexpected tag 'filename' found");
846 break;
847 }
848 }
849
850 void endPath()
851 {
852 switch (m_state)
853 {
854 case InFile:
855 {
856 TagFileInfo *info = m_curCompound.getFileInfo();
857 if (info) info->path = m_curString;
858 }
859 break;
860 case InDir:
861 {
862 TagDirInfo *info = m_curCompound.getDirInfo();
863 if (info) info->path = m_curString;
864 }
865 break;
866 default:
867 p_warn("Unexpected tag 'path' found");
868 break;
869 }
870 }
871
873 {
874 if (m_state==InMember)
875 {
876 m_curMember.anchor = m_curString;
877 }
878 else if (m_state==InClass)
879 {
880 TagClassInfo *info = m_curCompound.getClassInfo();
881 if (info) info->anchor = m_curString;
882 }
883 else
884 {
885 p_warn("Unexpected tag 'anchor' found");
886 }
887 }
888
890 {
891 if (m_state==InMember)
892 {
893 m_curMember.clangId = m_curString;
894 }
895 else if (m_state==InClass)
896 {
897 TagClassInfo *info = m_curCompound.getClassInfo();
898 if (info) info->clangId = m_curString;
899 }
900 else if (m_state==InNamespace)
901 {
902 TagNamespaceInfo *info = m_curCompound.getNamespaceInfo();
903 if (info) info->clangId = m_curString;
904 }
905 else
906 {
907 p_warn("Unexpected tag 'clangid' found");
908 }
909 }
910
911
912
914 {
915 if (m_state==InMember)
916 {
917 m_curMember.anchorFile = m_curString;
918 }
919 else
920 {
921 p_warn("Unexpected tag 'anchorfile' found");
922 }
923 }
924
926 {
927 if (m_state==InMember)
928 {
929 m_curMember.arglist = m_curString;
930 }
931 else
932 {
933 p_warn("Unexpected tag 'arglist' found");
934 }
935 }
936
937 void endTitle()
938 {
939 switch (m_state)
940 {
941 case InGroup:
942 {
943 TagGroupInfo *info = m_curCompound.getGroupInfo();
944 if (info) info->title = m_curString;
945 }
946 break;
947 case InPage:
948 {
949 TagPageInfo *info = m_curCompound.getPageInfo();
950 if (info) info->title = m_curString;
951 }
952 break;
953 default:
954 p_warn("Unexpected tag 'title' found");
955 break;
956 }
957 }
958
960 {
961 if (m_state==InGroup)
962 {
963 TagGroupInfo *info = m_curCompound.getGroupInfo();
964 if (info) info->subgroupList.push_back(m_curString.str());
965 }
966 else
967 {
968 p_warn("Unexpected tag 'subgroup' found");
969 }
970 }
971
975
977 {
978 }
979
980 void buildMemberList(const std::shared_ptr<Entry> &ce,const std::vector<TagMemberInfo> &members);
981 void addDocAnchors(const std::shared_ptr<Entry> &e,const std::vector<TagAnchorInfo> &l);
982
983
997 };
998 private:
999
1000 void p_warn(const char *fmt)
1001 {
1002 QCString fileName = m_locator->fileName();
1003 ::warn_(fileName,m_locator->lineNr(),"%s", fmt);
1004 }
1005
1006 void p_warn(const char *fmt,const char *s)
1007 {
1008 QCString fileName = m_locator->fileName();
1009 ::warn_(fileName,m_locator->lineNr(),fmt,s);
1010 }
1011
1012
1013 //------------------------------------
1014
1015 std::vector< TagCompoundVariant > m_tagFileCompounds;
1017
1021
1027 std::stack<State> m_stateStack;
1028 const XMLLocator *m_locator = nullptr;
1029};
1030
1031//---------------------------------------------------------------------------------------------------------------
1032
1034{
1035 using StartCallback = std::function<void(TagFileParser&,const XMLHandlers::Attributes&)>;
1036 using EndCallback = std::function<void(TagFileParser&)>;
1037
1040};
1041
1043{
1044 return [fn](TagFileParser &parser,const XMLHandlers::Attributes &attr) { (parser.*fn)(attr); };
1045}
1046
1048{
1049 return [fn](TagFileParser &parser) { (parser.*fn)(); };
1050}
1051
1052static const std::map< std::string, ElementCallbacks > g_elementHandlers =
1053{
1054 // name, start element callback, end element callback
1081};
1082
1083//---------------------------------------------------------------------------------------------------------------
1084
1092
1093static const std::map< std::string, CompoundFactory > g_compoundFactory =
1094{
1095 // kind tag state creation function
1106 { "file", { TagFileParser::InFile, []() { return TagCompoundVariant::make<TagFileInfo>(); } } },
1107 { "namespace", { TagFileParser::InNamespace, []() { return TagCompoundVariant::make<TagNamespaceInfo>(); } } },
1108 { "concept", { TagFileParser::InConcept, []() { return TagCompoundVariant::make<TagConceptInfo>(); } } },
1109 { "module", { TagFileParser::InModule, []() { return TagCompoundVariant::make<TagModuleInfo>(); } } },
1110 { "group", { TagFileParser::InGroup, []() { return TagCompoundVariant::make<TagGroupInfo>(); } } },
1111 { "page", { TagFileParser::InPage, []() { return TagCompoundVariant::make<TagPageInfo>(); } } },
1112 { "package", { TagFileParser::InPackage, []() { return TagCompoundVariant::make<TagPackageInfo>(); } } },
1113 { "dir", { TagFileParser::InDir, []() { return TagCompoundVariant::make<TagDirInfo>(); } } }
1114};
1115
1116//---------------------------------------------------------------------------------------------------------------
1117
1119{
1120 //printf("startElement '%s'\n",qPrint(name));
1121 auto it = g_elementHandlers.find(name.str());
1122 if (it!=std::end(g_elementHandlers))
1123 {
1124 it->second.startCb(*this,attrib);
1125 }
1126 else
1127 {
1128 p_warn("Unknown start tag '%s' found!",qPrint(name));
1129 }
1130}
1131
1133{
1134 //printf("endElement '%s'\n",qPrint(name));
1135 auto it = g_elementHandlers.find(name.str());
1136 if (it!=std::end(g_elementHandlers))
1137 {
1138 it->second.endCb(*this);
1139 }
1140 else
1141 {
1142 p_warn("Unknown end tag '%s' found!",qPrint(name));
1143 }
1144}
1145
1147{
1148 m_curString = "";
1149 std::string kind = XMLHandlers::value(attrib,"kind");
1150 std::string isObjC = XMLHandlers::value(attrib,"objc");
1151
1152 auto it = g_compoundFactory.find(kind);
1153 if (it!=g_compoundFactory.end())
1154 {
1155 m_curCompound = it->second.make_instance();
1156 m_state = it->second.state;
1157 TagCompoundInfo *info = m_curCompound.getCompoundInfo();
1158 if (info) info->lineNr = m_locator->lineNr();
1159 }
1160 else
1161 {
1162 p_warn("Unknown compound attribute '%s' found!",kind.c_str());
1163 m_state = Invalid;
1164 }
1165
1166 TagClassInfo *classInfo = m_curCompound.getClassInfo();
1167 if (isObjC=="yes" && classInfo)
1168 {
1169 classInfo->isObjC = TRUE;
1170 }
1171}
1172
1173/*! Dumps the internal structures. For debugging only! */
1175{
1176 Debug::print(Debug::Tag,0,"-------- Results --------\n");
1177 //============== CLASSES
1178 for (const auto &comp : m_tagFileCompounds)
1179 {
1180 if (comp.type()==TagCompoundVariant::Type::Class)
1181 {
1182 const TagClassInfo *cd = comp.getClassInfo();
1183 Debug::print(Debug::Tag,0,"class '%s'\n",qPrint(cd->name));
1184 Debug::print(Debug::Tag,0," filename '%s'\n",qPrint(cd->filename));
1185 for (const BaseInfo &bi : cd->bases)
1186 {
1187 Debug::print(Debug::Tag,0, " base: %s \n", bi.name.isEmpty() ? "" : qPrint(bi.name) );
1188 }
1189
1190 for (const auto &md : cd->members)
1191 {
1192 Debug::print(Debug::Tag,0," member:\n");
1193 Debug::print(Debug::Tag,0," kind: '%s'\n",qPrint(md.kind));
1194 Debug::print(Debug::Tag,0," name: '%s'\n",qPrint(md.name));
1195 Debug::print(Debug::Tag,0," anchor: '%s'\n",qPrint(md.anchor));
1196 Debug::print(Debug::Tag,0," arglist: '%s'\n",qPrint(md.arglist));
1197 }
1198 }
1199 }
1200 //============== CONCEPTS
1201 for (const auto &comp : m_tagFileCompounds)
1202 {
1203 if (comp.type()==TagCompoundVariant::Type::Concept)
1204 {
1205 const TagConceptInfo *cd = comp.getConceptInfo();
1206
1207 Debug::print(Debug::Tag,0,"concept '%s'\n",qPrint(cd->name));
1208 Debug::print(Debug::Tag,0," filename '%s'\n",qPrint(cd->filename));
1209 }
1210 }
1211 //============== MODULES
1212 for (const auto &comp : m_tagFileCompounds)
1213 {
1214 if (comp.type()==TagCompoundVariant::Type::Module)
1215 {
1216 const TagModuleInfo *mi = comp.getModuleInfo();
1217
1218 Debug::print(Debug::Tag,0,"module '%s'\n",qPrint(mi->name));
1219 Debug::print(Debug::Tag,0," filename '%s'\n",qPrint(mi->filename));
1220 }
1221 }
1222 //============== NAMESPACES
1223 for (const auto &comp : m_tagFileCompounds)
1224 {
1225 if (comp.type()==TagCompoundVariant::Type::Namespace)
1226 {
1227 const TagNamespaceInfo *nd = comp.getNamespaceInfo();
1228
1229 Debug::print(Debug::Tag,0,"namespace '%s'\n",qPrint(nd->name));
1230 Debug::print(Debug::Tag,0," filename '%s'\n",qPrint(nd->filename));
1231 for (const auto &cls : nd->classList)
1232 {
1233 Debug::print(Debug::Tag,0, " class: %s \n", cls.c_str() );
1234 }
1235
1236 for (const auto &md : nd->members)
1237 {
1238 Debug::print(Debug::Tag,0," member:\n");
1239 Debug::print(Debug::Tag,0," kind: '%s'\n",qPrint(md.kind));
1240 Debug::print(Debug::Tag,0," name: '%s'\n",qPrint(md.name));
1241 Debug::print(Debug::Tag,0," anchor: '%s'\n",qPrint(md.anchor));
1242 Debug::print(Debug::Tag,0," arglist: '%s'\n",qPrint(md.arglist));
1243 }
1244 }
1245 }
1246
1247 //============== FILES
1248 for (const auto &comp : m_tagFileCompounds)
1249 {
1250 if (comp.type()==TagCompoundVariant::Type::File)
1251 {
1252 const TagFileInfo *fd = comp.getFileInfo();
1253
1254 Debug::print(Debug::Tag,0,"file '%s'\n",qPrint(fd->name));
1255 Debug::print(Debug::Tag,0," filename '%s'\n",qPrint(fd->filename));
1256 for (const auto &ns : fd->namespaceList)
1257 {
1258 Debug::print(Debug::Tag,0, " namespace: %s \n", ns.c_str() );
1259 }
1260 for (const auto &cs : fd->classList)
1261 {
1262 Debug::print(Debug::Tag,0, " class: %s \n", cs.c_str() );
1263 }
1264
1265 for (const auto &md : fd->members)
1266 {
1267 Debug::print(Debug::Tag,0," member:\n");
1268 Debug::print(Debug::Tag,0," kind: '%s'\n",qPrint(md.kind));
1269 Debug::print(Debug::Tag,0," name: '%s'\n",qPrint(md.name));
1270 Debug::print(Debug::Tag,0," anchor: '%s'\n",qPrint(md.anchor));
1271 Debug::print(Debug::Tag,0," arglist: '%s'\n",qPrint(md.arglist));
1272 }
1273
1274 for (const auto &ii : fd->includes)
1275 {
1276 Debug::print(Debug::Tag,0," includes id: %s name: %s\n",qPrint(ii.id),qPrint(ii.name));
1277 }
1278 }
1279 }
1280
1281 //============== GROUPS
1282 for (const auto &comp : m_tagFileCompounds)
1283 {
1284 if (comp.type()==TagCompoundVariant::Type::Group)
1285 {
1286 const TagGroupInfo *gd = comp.getGroupInfo();
1287 Debug::print(Debug::Tag,0,"group '%s'\n",qPrint(gd->name));
1288 Debug::print(Debug::Tag,0," filename '%s'\n",qPrint(gd->filename));
1289
1290 for (const auto &ns : gd->namespaceList)
1291 {
1292 Debug::print(Debug::Tag,0, " namespace: %s \n", ns.c_str() );
1293 }
1294 for (const auto &cs : gd->classList)
1295 {
1296 Debug::print(Debug::Tag,0, " class: %s \n", cs.c_str() );
1297 }
1298 for (const auto &fi : gd->fileList)
1299 {
1300 Debug::print(Debug::Tag,0, " file: %s \n", fi.c_str() );
1301 }
1302 for (const auto &sg : gd->subgroupList)
1303 {
1304 Debug::print(Debug::Tag,0, " subgroup: %s \n", sg.c_str() );
1305 }
1306 for (const auto &pg : gd->pageList)
1307 {
1308 Debug::print(Debug::Tag,0, " page: %s \n", pg.c_str() );
1309 }
1310
1311 for (const auto &md : gd->members)
1312 {
1313 Debug::print(Debug::Tag,0," member:\n");
1314 Debug::print(Debug::Tag,0," kind: '%s'\n",qPrint(md.kind));
1315 Debug::print(Debug::Tag,0," name: '%s'\n",qPrint(md.name));
1316 Debug::print(Debug::Tag,0," anchor: '%s'\n",qPrint(md.anchor));
1317 Debug::print(Debug::Tag,0," arglist: '%s'\n",qPrint(md.arglist));
1318 }
1319 }
1320 }
1321
1322 //============== PAGES
1323 for (const auto &comp : m_tagFileCompounds)
1324 {
1325 if (comp.type()==TagCompoundVariant::Type::Page)
1326 {
1327 const TagPageInfo *pd = comp.getPageInfo();
1328 Debug::print(Debug::Tag,0,"page '%s'\n",qPrint(pd->name));
1329 Debug::print(Debug::Tag,0," title '%s'\n",qPrint(pd->title));
1330 Debug::print(Debug::Tag,0," filename '%s'\n",qPrint(pd->filename));
1331 }
1332 }
1333
1334 //============== DIRS
1335 for (const auto &comp : m_tagFileCompounds)
1336 {
1337 if (comp.type()==TagCompoundVariant::Type::Dir)
1338 {
1339 const TagDirInfo *dd = comp.getDirInfo();
1340 {
1341 Debug::print(Debug::Tag,0,"dir '%s'\n",qPrint(dd->name));
1342 Debug::print(Debug::Tag,0," path '%s'\n",qPrint(dd->path));
1343 for (const auto &fi : dd->fileList)
1344 {
1345 Debug::print(Debug::Tag,0, " file: %s \n", fi.c_str() );
1346 }
1347 for (const auto &sd : dd->subdirList)
1348 {
1349 Debug::print(Debug::Tag,0, " subdir: %s \n", sd.c_str() );
1350 }
1351 }
1352 }
1353 }
1354 Debug::print(Debug::Tag,0,"-------------------------\n");
1355}
1356
1357void TagFileParser::addDocAnchors(const std::shared_ptr<Entry> &e,const std::vector<TagAnchorInfo> &l)
1358{
1359 for (const auto &ta : l)
1360 {
1361 if (SectionManager::instance().find(QCString(ta.label))==nullptr)
1362 {
1363 //printf("New sectionInfo file=%s anchor=%s\n",
1364 // qPrint(ta->fileName),qPrint(ta->label));
1366 ta.label,ta.fileName,-1,ta.title,
1368 e->anchors.push_back(si);
1369 }
1370 else
1371 {
1372 //printf("Replace sectionInfo file=%s anchor=%s\n",
1373 // qPrint(ta->fileName),qPrint(ta->label));
1375 ta.label,ta.fileName,-1,ta.title,
1377 }
1378 }
1379}
1380
1381void TagFileParser::buildMemberList(const std::shared_ptr<Entry> &ce,const std::vector<TagMemberInfo> &members)
1382{
1383 for (const auto &tmi : members)
1384 {
1385 std::shared_ptr<Entry> me = std::make_shared<Entry>();
1386 me->type = tmi.type;
1387 me->name = tmi.name;
1388 me->args = tmi.arglist;
1389 if (!me->args.isEmpty())
1390 {
1391 me->argList = *stringToArgumentList(SrcLangExt::Cpp,me->args);
1392 }
1393 if (tmi.enumValues.size()>0)
1394 {
1395 me->spec.setStrong(true);
1396 for (const auto &evi : tmi.enumValues)
1397 {
1398 std::shared_ptr<Entry> ev = std::make_shared<Entry>();
1399 ev->type = "@";
1400 ev->name = evi.name;
1401 ev->id = evi.clangid;
1402 ev->section = EntryType::makeVariable();
1403 ev->tagInfoData.tagName = m_tagName;
1404 ev->tagInfoData.anchor = evi.anchor;
1405 ev->tagInfoData.fileName = evi.file;
1406 ev->hasTagInfo = TRUE;
1407 me->moveToSubEntryAndKeep(ev);
1408 }
1409 }
1410 me->protection = tmi.prot;
1411 me->virt = tmi.virt;
1412 me->isStatic = tmi.isStatic;
1413 me->fileName = ce->fileName;
1414 me->id = tmi.clangId;
1415 me->startLine = tmi.lineNr;
1416 if (ce->section.isGroupDoc())
1417 {
1418 me->groups.emplace_back(ce->name,Grouping::GROUPING_INGROUP);
1419 }
1420 addDocAnchors(me,tmi.docAnchors);
1421 me->tagInfoData.tagName = m_tagName;
1422 me->tagInfoData.anchor = tmi.anchor;
1423 me->tagInfoData.fileName = tmi.anchorFile;
1424 me->hasTagInfo = TRUE;
1425 if (tmi.kind=="define")
1426 {
1427 me->type="#define";
1428 me->section = EntryType::makeDefine();
1429 }
1430 else if (tmi.kind=="enumvalue")
1431 {
1432 me->section = EntryType::makeVariable();
1433 me->mtype = MethodTypes::Method;
1434 }
1435 else if (tmi.kind=="property")
1436 {
1437 me->section = EntryType::makeVariable();
1438 me->mtype = MethodTypes::Property;
1439 }
1440 else if (tmi.kind=="event")
1441 {
1442 me->section = EntryType::makeVariable();
1443 me->mtype = MethodTypes::Event;
1444 }
1445 else if (tmi.kind=="variable")
1446 {
1447 me->section = EntryType::makeVariable();
1448 me->mtype = MethodTypes::Method;
1449 }
1450 else if (tmi.kind=="typedef")
1451 {
1452 me->section = EntryType::makeVariable();
1453 me->type.prepend("typedef ");
1454 me->mtype = MethodTypes::Method;
1455 }
1456 else if (tmi.kind=="enumeration")
1457 {
1458 me->section = EntryType::makeEnum();
1459 me->mtype = MethodTypes::Method;
1460 }
1461 else if (tmi.kind=="function")
1462 {
1463 me->section = EntryType::makeFunction();
1464 me->mtype = MethodTypes::Method;
1465 }
1466 else if (tmi.kind=="signal")
1467 {
1468 me->section = EntryType::makeFunction();
1469 me->mtype = MethodTypes::Signal;
1470 }
1471 else if (tmi.kind=="prototype")
1472 {
1473 me->section = EntryType::makeFunction();
1474 me->mtype = MethodTypes::Method;
1475 }
1476 else if (tmi.kind=="friend")
1477 {
1478 me->section = EntryType::makeFunction();
1479 me->type.prepend("friend ");
1480 me->mtype = MethodTypes::Method;
1481 }
1482 else if (tmi.kind=="dcop")
1483 {
1484 me->section = EntryType::makeFunction();
1485 me->mtype = MethodTypes::DCOP;
1486 }
1487 else if (tmi.kind=="slot")
1488 {
1489 me->section = EntryType::makeFunction();
1490 me->mtype = MethodTypes::Slot;
1491 }
1492 ce->moveToSubEntryAndKeep(me);
1493 }
1494}
1495
1496/*! Injects the info gathered by the XML parser into the Entry tree.
1497 * This tree contains the information extracted from the input in a
1498 * "unrelated" form.
1499 */
1500void TagFileParser::buildLists(const std::shared_ptr<Entry> &root)
1501{
1502 // build class list
1503 for (const auto &comp : m_tagFileCompounds)
1504 {
1505 const TagClassInfo *tci = comp.getClassInfo();
1506 if (tci)
1507 {
1508 std::shared_ptr<Entry> ce = std::make_shared<Entry>();
1509 ce->section = EntryType::makeClass();
1510 switch (tci->kind)
1511 {
1512 case TagClassInfo::Kind::Class: break;
1513 case TagClassInfo::Kind::Struct: ce->spec = TypeSpecifier().setStruct(true); break;
1514 case TagClassInfo::Kind::Union: ce->spec = TypeSpecifier().setUnion(true); break;
1515 case TagClassInfo::Kind::Interface: ce->spec = TypeSpecifier().setInterface(true); break;
1516 case TagClassInfo::Kind::Enum: ce->spec = TypeSpecifier().setEnum(true); break;
1517 case TagClassInfo::Kind::Exception: ce->spec = TypeSpecifier().setException(true); break;
1518 case TagClassInfo::Kind::Protocol: ce->spec = TypeSpecifier().setProtocol(true); break;
1519 case TagClassInfo::Kind::Category: ce->spec = TypeSpecifier().setCategory(true); break;
1520 case TagClassInfo::Kind::Service: ce->spec = TypeSpecifier().setService(true); break;
1521 case TagClassInfo::Kind::Singleton: ce->spec = TypeSpecifier().setSingleton(true); break;
1522 case TagClassInfo::Kind::None: // should never happen, means not properly initialized
1523 assert(tci->kind != TagClassInfo::Kind::None);
1524 break;
1525 }
1526 ce->name = tci->name;
1528 {
1529 ce->name+="-p";
1530 }
1531 addDocAnchors(ce,tci->docAnchors);
1532 ce->tagInfoData.tagName = m_tagName;
1533 ce->tagInfoData.anchor = tci->anchor;
1534 ce->tagInfoData.fileName = tci->filename;
1535 ce->startLine = tci->lineNr;
1536 ce->fileName = m_tagName;
1537 ce->hasTagInfo = TRUE;
1538 ce->id = tci->clangId;
1539 ce->lang = tci->isObjC ? SrcLangExt::ObjC : SrcLangExt::Unknown;
1540 // transfer base class list
1541 ce->extends = tci->bases;
1542 if (!tci->templateArguments.empty())
1543 {
1544 ArgumentList al;
1545 for (const auto &argName : tci->templateArguments)
1546 {
1547 Argument a;
1548 a.type = "class";
1549 a.name = argName.c_str();
1550 al.push_back(a);
1551 }
1552 ce->tArgLists.push_back(al);
1553 }
1554
1555 buildMemberList(ce,tci->members);
1556 root->moveToSubEntryAndKeep(ce);
1557 }
1558 }
1559
1560 // build file list
1561 for (const auto &comp : m_tagFileCompounds)
1562 {
1563 const TagFileInfo *tfi = comp.getFileInfo();
1564 if (tfi)
1565 {
1566 std::shared_ptr<Entry> fe = std::make_shared<Entry>();
1567 fe->section = guessSection(tfi->name);
1568 fe->name = tfi->name;
1569 addDocAnchors(fe,tfi->docAnchors);
1570 fe->tagInfoData.tagName = m_tagName;
1571 fe->tagInfoData.fileName = tfi->filename;
1572 fe->hasTagInfo = TRUE;
1573
1574 QCString fullName = m_tagName+":"+tfi->path+stripPath(tfi->name);
1575 fe->fileName = fullName;
1576 fe->startLine = tfi->lineNr;
1577 //printf("createFileDef() filename=%s\n",qPrint(tfi->filename));
1578 QCString tagid = m_tagName+":"+tfi->path;
1579 auto fd = createFileDef(tagid, tfi->name,m_tagName, tfi->filename);
1580 FileName *mn = Doxygen::inputNameLinkedMap->find(tfi->name);
1581 if (mn)
1582 {
1583 mn->push_back(std::move(fd));
1584 }
1585 else
1586 {
1587 mn = Doxygen::inputNameLinkedMap->add(tfi->name,fullName);
1588 mn->push_back(std::move(fd));
1589 }
1590 buildMemberList(fe,tfi->members);
1591 root->moveToSubEntryAndKeep(fe);
1592 }
1593 }
1594
1595 // build concept list
1596 for (const auto &comp : m_tagFileCompounds)
1597 {
1598 const TagConceptInfo *tci = comp.getConceptInfo();
1599 if (tci)
1600 {
1601 std::shared_ptr<Entry> ce = std::make_shared<Entry>();
1602 ce->section = EntryType::makeConcept();
1603 ce->name = tci->name;
1604 addDocAnchors(ce,tci->docAnchors);
1605 ce->tagInfoData.tagName = m_tagName;
1606 ce->tagInfoData.fileName = tci->filename;
1607 ce->startLine = tci->lineNr;
1608 ce->fileName = m_tagName;
1609 ce->hasTagInfo = TRUE;
1610 ce->id = tci->clangId;
1611
1612 root->moveToSubEntryAndKeep(ce);
1613 }
1614 }
1615
1616 // build module list
1617 for (const auto &comp : m_tagFileCompounds)
1618 {
1619 const TagModuleInfo *tmi = comp.getModuleInfo();
1620 if (tmi)
1621 {
1622 auto &mm = ModuleManager::instance();
1623 mm.createModuleDef(tmi->filename,tmi->lineNr,1,true,tmi->name,QCString());
1624 mm.addTagInfo(tmi->filename,m_tagName,tmi->clangId);
1625
1626 ModuleDef *mod = mm.getPrimaryInterface(tmi->name);
1627 if (mod && !tmi->docAnchors.empty())
1628 {
1629 std::vector<const SectionInfo *> anchorList;
1630 for (const auto &ta : tmi->docAnchors)
1631 {
1632 if (SectionManager::instance().find(QCString(ta.label))==nullptr)
1633 {
1634 //printf("New sectionInfo file=%s anchor=%s\n",
1635 // qPrint(ta->fileName),qPrint(ta->label));
1637 ta.label,ta.fileName,-1,ta.title,
1639 anchorList.push_back(si);
1640 }
1641 else
1642 {
1643 p_warn("Duplicate anchor %s found",qPrint(ta.label));
1644 }
1645 }
1646 mod->addSectionsToDefinition(anchorList);
1647 }
1648 }
1649 }
1650
1651
1652 // build namespace list
1653 for (const auto &comp : m_tagFileCompounds)
1654 {
1655 const TagNamespaceInfo *tni = comp.getNamespaceInfo();
1656 if (tni)
1657 {
1658 std::shared_ptr<Entry> ne = std::make_shared<Entry>();
1659 ne->section = EntryType::makeNamespace();
1660 ne->name = tni->name;
1661 addDocAnchors(ne,tni->docAnchors);
1662 ne->tagInfoData.tagName = m_tagName;
1663 ne->tagInfoData.fileName = tni->filename;
1664 ne->startLine = tni->lineNr;
1665 ne->fileName = m_tagName;
1666 ne->hasTagInfo = TRUE;
1667 ne->id = tni->clangId;
1668
1669 buildMemberList(ne,tni->members);
1670 root->moveToSubEntryAndKeep(ne);
1671 }
1672 }
1673
1674 // build package list
1675 for (const auto &comp : m_tagFileCompounds)
1676 {
1677 const TagPackageInfo *tpgi = comp.getPackageInfo();
1678 if (tpgi)
1679 {
1680 std::shared_ptr<Entry> pe = std::make_shared<Entry>();
1681 pe->section = EntryType::makePackage();
1682 pe->name = tpgi->name;
1683 addDocAnchors(pe,tpgi->docAnchors);
1684 pe->tagInfoData.tagName = m_tagName;
1685 pe->tagInfoData.fileName = tpgi->filename;
1686 pe->startLine = tpgi->lineNr;
1687 pe->fileName = m_tagName;
1688 pe->hasTagInfo = TRUE;
1689
1690 buildMemberList(pe,tpgi->members);
1691 root->moveToSubEntryAndKeep(pe);
1692 }
1693 }
1694
1695 // build group list
1696 for (const auto &comp : m_tagFileCompounds)
1697 {
1698 const TagGroupInfo *tgi = comp.getGroupInfo();
1699 if (tgi)
1700 {
1701 std::shared_ptr<Entry> ge = std::make_shared<Entry>();
1702 ge->section = EntryType::makeGroupDoc();
1703 ge->name = tgi->name;
1704 ge->type = tgi->title;
1705 addDocAnchors(ge,tgi->docAnchors);
1706 ge->tagInfoData.tagName = m_tagName;
1707 ge->tagInfoData.fileName = tgi->filename;
1708 ge->startLine = tgi->lineNr;
1709 ge->fileName = m_tagName;
1710 ge->hasTagInfo = TRUE;
1711
1712 buildMemberList(ge,tgi->members);
1713 root->moveToSubEntryAndKeep(ge);
1714 }
1715 }
1716
1717 for (const auto &comp : m_tagFileCompounds)
1718 {
1719 const TagGroupInfo *tgi = comp.getGroupInfo();
1720 if (tgi)
1721 {
1722 // set subgroup relations bug_774118
1723 for (const auto &sg : tgi->subgroupList)
1724 {
1725 const auto &children = root->children();
1726 auto i = std::find_if(children.begin(),children.end(),
1727 [&](const std::shared_ptr<Entry> &e) { return e->name == sg.c_str(); });
1728 if (i!=children.end())
1729 {
1730 (*i)->groups.emplace_back(tgi->name,Grouping::GROUPING_INGROUP);
1731 }
1732 }
1733 }
1734 }
1735
1736 // build page list
1737 for (const auto &comp : m_tagFileCompounds)
1738 {
1739 const TagPageInfo *tpi = comp.getPageInfo();
1740 if (tpi)
1741 {
1742 std::shared_ptr<Entry> pe = std::make_shared<Entry>();
1743 bool isIndex = (stripExtensionGeneral(tpi->filename,getFileNameExtension(tpi->filename))=="index");
1744 pe->section = isIndex ? EntryType::makeMainpageDoc() : EntryType::makePageDoc();
1745 pe->name = tpi->name;
1746 pe->args = tpi->title;
1747 for (const auto &subpage : tpi->subpages)
1748 {
1749 // we add subpage labels as a kind of "inheritance" relation to prevent
1750 // needing to add another list to the Entry class.
1751 pe->extends.emplace_back(stripExtension(QCString(subpage)),Protection::Public,Specifier::Normal);
1752 }
1753 addDocAnchors(pe,tpi->docAnchors);
1754 pe->tagInfoData.tagName = m_tagName;
1755 pe->tagInfoData.fileName = stripExtension(tpi->filename);
1756 pe->startLine = tpi->lineNr;
1757 pe->fileName = m_tagName;
1758 pe->hasTagInfo = TRUE;
1759 root->moveToSubEntryAndKeep(pe);
1760 }
1761 }
1762}
1763
1765{
1766 for (const auto &comp : m_tagFileCompounds)
1767 {
1768 const TagFileInfo *tfi = comp.getFileInfo();
1769 if (tfi)
1770 {
1771 //printf("tag file tagName=%s path=%s name=%s\n",qPrint(m_tagName),qPrint(tfi->path),qPrint(tfi->name));
1772 FileName *fn = Doxygen::inputNameLinkedMap->find(tfi->name);
1773 if (fn)
1774 {
1775 for (const auto &fd : *fn)
1776 {
1777 //printf("input file path=%s name=%s\n",qPrint(fd->getPath()),qPrint(fd->name()));
1778 if (fd->getPath()==QCString(m_tagName+":"+tfi->path))
1779 {
1780 //printf("found\n");
1781 for (const auto &ii : tfi->includes)
1782 {
1783 //printf("ii->name='%s'\n",qPrint(ii->name));
1784 FileName *ifn = Doxygen::inputNameLinkedMap->find(ii.name);
1785 ASSERT(ifn!=nullptr);
1786 if (ifn)
1787 {
1788 for (const auto &ifd : *ifn)
1789 {
1790 //printf("ifd->getOutputFileBase()=%s ii->id=%s\n",
1791 // qPrint(ifd->getOutputFileBase()),qPrint(ii->id));
1792 if (ifd->getOutputFileBase()==QCString(ii.id))
1793 {
1795 if (ii.isModule)
1796 {
1798 }
1799 else if (ii.isImported)
1800 {
1802 }
1803 else if (ii.isLocal)
1804 {
1806 }
1807 fd->addIncludeDependency(ifd.get(),ii.text,kind);
1808 }
1809 }
1810 }
1811 }
1812 }
1813 }
1814 }
1815 }
1816 }
1817}
1818
1819} // namespace
1820
1821// ----------------- public part -----------------------------------------------
1822
1823void parseTagFile(const std::shared_ptr<Entry> &root,const char *fullName)
1824{
1825 TagFileParser tagFileParser(fullName);
1826 QCString inputStr = fileToString(fullName);
1827 XMLHandlers handlers;
1828 // connect the generic events handlers of the XML parser to the specific handlers of the tagFileParser object
1829 handlers.startDocument = [&tagFileParser]() { tagFileParser.startDocument(); };
1830 handlers.startElement = [&tagFileParser](const std::string &name,const XMLHandlers::Attributes &attrs) { tagFileParser.startElement(QCString(name),attrs); };
1831 handlers.endElement = [&tagFileParser](const std::string &name) { tagFileParser.endElement(QCString(name)); };
1832 handlers.characters = [&tagFileParser](const std::string &chars) { tagFileParser.characters(QCString(chars)); };
1833 handlers.error = [&tagFileParser](const std::string &fileName,int lineNr,const std::string &msg) { tagFileParser.error(QCString(fileName),lineNr,QCString(msg)); };
1834 XMLParser parser(handlers);
1835 tagFileParser.setDocumentLocator(&parser);
1836 parser.parse(fullName,inputStr.data(),Debug::isFlagSet(Debug::Lex_xml),
1837 [&]() { DebugLex::print(Debug::Lex_xml,"Entering","libxml/xml.l",fullName); },
1838 [&]() { DebugLex::print(Debug::Lex_xml,"Finished", "libxml/xml.l",fullName); }
1839 );
1840 tagFileParser.buildLists(root);
1841 tagFileParser.addIncludes();
1843 {
1844 tagFileParser.dump();
1845 }
1846}
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:44
@ Lex_xml
Definition debug.h:69
static void print(DebugMask mask, int prio, const char *fmt,...)
Definition debug.cpp:81
static bool isFlagSet(const DebugMask mask)
Definition debug.cpp:135
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
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:150
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())
Replace an existing section with a new one Return a non-owning pointer to the newly added section.
Definition section.h:154
SectionInfo * add(const SectionInfo &si)
Add a new section given the data of an existing section.
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 p_warn(const char *fmt, const char *s)
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
void warn_(const QCString &file, int line, const char *fmt,...)
Definition message.cpp:217
void msg(const char *fmt,...)
Definition message.cpp:98
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
Definition trace.h:153
const char * qPrint(const char *s)
Definition qcstring.h:672
#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)
@ 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:5292
QCString fileToString(const QCString &name, bool filter, bool isSourceCode)
Definition util.cpp:1414
QCString stripExtensionGeneral(const QCString &fName, const QCString &ext)
Definition util.cpp:5255
QCString stripExtension(const QCString &fName)
Definition util.cpp:5265
EntryType guessSection(const QCString &name)
Definition util.cpp:349
QCString getFileNameExtension(const QCString &fn)
Definition util.cpp:5591
A bunch of utility functions.