@@ -46,6 +46,7 @@ typedef struct tagFileX {
4646struct inputSpec {
4747 const char * tagFileName ;
4848 char * tempFileName ;
49+ bool indirect ;
4950};
5051
5152struct actionSpec {
@@ -54,6 +55,7 @@ struct actionSpec {
5455 ACTION_FIND = 1 << 0 ,
5556 ACTION_LIST = 1 << 1 ,
5657 ACTION_LIST_PTAGS = 1 << 2 ,
58+ ACTION_LIST_INCLUDED = 1 << 3 ,
5759 } action ;
5860 const char * name ; /* for ACTION_FIND */
5961 bool canonicalizing ;
@@ -605,6 +607,8 @@ static const char *const Usage =
605607 " \"-\" indicates arguments after this as NAME(s) even if they start with -.\n"
606608 " -D | --list-pseudo-tags\n"
607609 " List pseudo tags.\n"
610+ " -L | --list-included\n"
611+ " List included tag files.\n"
608612 "Options:\n"
609613 " -d | --debug\n"
610614 " Turn on debugging output.\n"
@@ -711,24 +715,55 @@ static void printVersion(void)
711715static void deleteInputSpec (void * data )
712716{
713717 struct inputSpec * inputSpec = data ;
718+
719+ if (inputSpec -> indirect )
720+ eFree ((void * )inputSpec -> tagFileName );
714721 if (inputSpec -> tempFileName )
715722 {
716723 remove (inputSpec -> tempFileName );
717724 eFree (inputSpec -> tempFileName );
718725 }
726+
719727 eFree (data );
720728}
721729
722- static void addInputSpec (ptrArray * inputSpecs , const char * name )
730+ static void addInputSpec (ptrArray * inputSpecs , const char * name , bool indirect )
723731{
724732 struct inputSpec * i = eMalloc (sizeof (struct inputSpec ));
725733
726- i -> tagFileName = name ;
734+ i -> tagFileName = indirect ? eStrdup ( name ): name ;
727735 i -> tempFileName = NULL ;
736+ i -> indirect = indirect ;
728737
729738 ptrArrayAdd (inputSpecs , i );
730739}
731740
741+
742+ static void loadIndirectTagFiles (struct inputSpec * inputSpec , ptrArray * inputSpecs )
743+ {
744+ tagEntry pentry ;
745+ tagFileX * const fileX = openTags (inputSpec );
746+
747+ if (tagsFindPseudoTag (fileX -> tagFile , & pentry , "!_READTAGS_INCLUDE" ,
748+ TAG_FULLMATCH ) == TagSuccess )
749+ {
750+ addInputSpec (inputSpecs , pentry .file , true);
751+
752+ while (tagsNext (fileX -> tagFile , & pentry ) == TagSuccess )
753+ {
754+ if (pentry .name == NULL
755+ || pentry .name [0 ] != '!'
756+ || pentry .name [1 ] != '_' )
757+ break ;
758+ if (strcmp (pentry .name , "!_READTAGS_INCLUDE" ) != 0 )
759+ continue ;
760+ addInputSpec (inputSpecs , pentry .file , true);
761+ }
762+ }
763+
764+ deleteTagFileX (fileX );
765+ }
766+
732767extern int main (int argc , char * * argv )
733768{
734769 int i ;
@@ -817,12 +852,14 @@ extern int main (int argc, char **argv)
817852 readOpts .matchOpts |= TAG_PARTIALMATCH ;
818853 else if (strcmp (optname , "list ") == 0 )
819854 actionSpec .action |= ACTION_LIST ;
855+ else if (strcmp (optname , "list - included ") == 0 )
856+ actionSpec .action |= ACTION_LIST_INCLUDED ;
820857 else if (strcmp (optname , "line - number ") == 0 )
821858 printOpts .lineNumber = true;
822859 else if (strcmp (optname , "tag - file ") == 0 )
823860 {
824861 if (i + 1 < argc )
825- addInputSpec (inputSpecs , argv [++ i ]);
862+ addInputSpec (inputSpecs , argv [++ i ], false );
826863 else
827864 printUsage (stderr , 1 );
828865 }
@@ -951,16 +988,19 @@ extern int main (int argc, char **argv)
951988 case 'l' :
952989 actionSpec .action |= ACTION_LIST ;
953990 break ;
991+ case 'L' :
992+ actionSpec .action |= ACTION_LIST_INCLUDED ;
993+ break ;
954994 case 'n' : printOpts .lineNumber = true; break ;
955995 case 't' :
956996 if (arg [j + 1 ] != '\0' )
957997 {
958998 const char * tname = arg + j + 1 ;
959- addInputSpec (inputSpecs , tname );
999+ addInputSpec (inputSpecs , tname , false );
9601000 j += strlen (tname );
9611001 }
9621002 else if (i + 1 < argc )
963- addInputSpec (inputSpecs , argv [++ i ]);
1003+ addInputSpec (inputSpecs , argv [++ i ], false );
9641004 else
9651005 printUsage (stderr , 1 );
9661006 break ;
@@ -1033,12 +1073,33 @@ extern int main (int argc, char **argv)
10331073 }
10341074
10351075 if (ptrArrayIsEmpty (inputSpecs ))
1036- addInputSpec (inputSpecs , "tags" );
1076+ addInputSpec (inputSpecs , "tags" , false);
1077+
1078+ unsigned int start = 0 ;
1079+ unsigned int end = ptrArrayCount (inputSpecs );
1080+ while (1 )
1081+ {
1082+ for (unsigned int i = start ; i < end ; i ++ )
1083+ {
1084+ struct inputSpec * inputSpec = ptrArrayItem (inputSpecs , i );
1085+ loadIndirectTagFiles (inputSpec , inputSpecs );
1086+ }
1087+ start = end ;
1088+ end = ptrArrayCount (inputSpecs );
1089+ if (start == end )
1090+ break ;
1091+ }
10371092
10381093 for (unsigned int i = 0 ; i < ptrArrayCount (inputSpecs ); i ++ )
10391094 {
10401095 struct inputSpec * inputSpec = ptrArrayItem (inputSpecs , i );
10411096
1097+ if (actionSpec .action & ACTION_LIST_INCLUDED )
1098+ {
1099+ if (inputSpec -> indirect )
1100+ puts (inputSpec -> tagFileName );
1101+ }
1102+
10421103 if (actionSpec .action & ACTION_LIST_PTAGS )
10431104 {
10441105 if (actionSpec .canonicalizing )
0 commit comments