@@ -35,7 +35,17 @@ struct canonWorkArea {
3535 bool absoluteOnly ;
3636};
3737
38- static const char * TagFileName = "tags" ;
38+ typedef struct tagFileX {
39+ const char * fileName ;
40+ tagFile * tagFile ;
41+ tagFileInfo info ;
42+ } tagFileX ;
43+
44+ struct inputSpec {
45+ const char * tagFileName ;
46+ char * tempFileName ;
47+ };
48+
3949static const char * ProgramName ;
4050static int debugMode ;
4151#ifdef READTAGS_DSL
@@ -323,27 +333,21 @@ static int copyFile (FILE *in, FILE *out)
323333 return 0 ;
324334}
325335
326- static void removeTagFile (void )
327- {
328- remove (TagFileName );
329- eFree ((char * )TagFileName );
330- }
331-
332- static const char * loadCtagsCWD (tagFile * const file , tagEntry * pentry )
336+ static const char * loadCtagsCWD (tagFileX * const fileX , tagEntry * pentry )
333337{
334- if (tagsFindPseudoTag (file , pentry , "!_TAG_PROC_CWD" ,
338+ if (tagsFindPseudoTag (fileX -> tagFile , pentry , "!_TAG_PROC_CWD" ,
335339 TAG_FULLMATCH ) != TagSuccess )
336340 {
337- int err = tagsGetErrno (file );
341+ int err = tagsGetErrno (fileX -> tagFile );
338342 if (!err )
339343 {
340344 fprintf (stderr , "%s: no !_TAG_PROC_CWD in %s\n" ,
341- ProgramName , TagFileName );
345+ ProgramName , fileX -> fileName );
342346 exit (1 );
343347 }
344348
345349 fprintf (stderr , "%s: cannot find !_TAG_PROC_CWD in %s: %s\n" ,
346- ProgramName , TagFileName , tagsStrerror (err ));
350+ ProgramName , fileX -> fileName , tagsStrerror (err ));
347351 exit (1 );
348352 }
349353
@@ -358,17 +362,45 @@ static const char *loadCtagsCWD (tagFile *const file, tagEntry *pentry)
358362 return pentry -> file ;
359363}
360364
361- static struct canonFnameCacheTable * makeCanonFnameCacheTable (tagFile * const file ,
365+ static struct canonFnameCacheTable * makeCanonFnameCacheTable (tagFileX * const fileX ,
362366 bool absoluteOnly )
363367{
364368 tagEntry pentry ;
365- const char * cwd = loadCtagsCWD (file , & pentry );
369+ const char * cwd = loadCtagsCWD (fileX , & pentry );
366370 return canonFnameCacheTableNew (cwd , absoluteOnly );
367371}
368372
369- static tagFile * openTags (const char * const filePath , tagFileInfo * const info )
373+ static tagFileX * makeTagFileX (const char * const filePath )
374+ {
375+ tagFileX * fileX = eMalloc (sizeof (* fileX ));
376+ fileX -> fileName = eStrdup (filePath );
377+ fileX -> tagFile = NULL ;
378+ memset (& fileX -> info , 0 , sizeof (fileX -> info ));
379+ return fileX ;
380+ }
381+
382+ static void deleteTagFileX (tagFileX * fileX )
383+ {
384+ eFree ((void * )fileX -> fileName );
385+ if (fileX -> tagFile )
386+ tagsClose (fileX -> tagFile );
387+ eFree (fileX );
388+
389+ }
390+
391+ static tagFileX * openTagFileX (tagFileX * fileX )
370392{
371- if (strcmp (filePath , "-" ) == 0 )
393+ fileX -> tagFile = tagsOpen (fileX -> fileName , & fileX -> info );
394+ return fileX ;
395+ }
396+
397+ static tagFileX * openTags (struct inputSpec * inputSpec )
398+ {
399+ tagFileX * fileX ;
400+
401+ if (inputSpec -> tempFileName )
402+ fileX = makeTagFileX (inputSpec -> tempFileName );
403+ else if (strcmp (inputSpec -> tagFileName , "-" ) == 0 )
372404 {
373405 char * tempName = NULL ;
374406 FILE * tempFP = tempFileFP ("w" , & tempName );
@@ -379,11 +411,14 @@ static tagFile *openTags (const char *const filePath, tagFileInfo *const info)
379411 ProgramName );
380412 exit (1 );
381413 }
382- TagFileName = tempName ;
383- atexit (removeTagFile );
414+
415+ fileX = makeTagFileX (tempName );
416+ inputSpec -> tempFileName = tempName ; /* Move the ownership. */
417+ tempName = NULL ; /* Don't touch this anymore. */
384418
385419 if (copyFile (stdin , tempFP ) < 0 )
386420 {
421+ deleteTagFileX (fileX );
387422 fclose (tempFP );
388423 exit (1 );
389424 }
@@ -392,14 +427,17 @@ static tagFile *openTags (const char *const filePath, tagFileInfo *const info)
392427 {
393428 fprintf (stderr , "%s: failed to flush a temporarily file for storing data from stdin\n" ,
394429 ProgramName );
430+ deleteTagFileX (fileX );
395431 fclose (tempFP );
396432 exit (1 );
397433 }
434+
398435 fclose (tempFP );
399- return tagsOpen (tempName , info );
400436 }
437+ else
438+ fileX = makeTagFileX (inputSpec -> tagFileName );
401439
402- return tagsOpen ( filePath , info );
440+ return openTagFileX ( fileX );
403441}
404442
405443static int hasPsuedoTag (tagFile * const file ,
@@ -412,38 +450,38 @@ static int hasPsuedoTag (tagFile *const file,
412450 && (strcmp (entry .file , exepectedValueAsInputField ) == 0 ));
413451}
414452
415- static void findTag (const char * const name , readOptions * readOpts ,
453+ static void findTag (struct inputSpec * inputSpec ,
454+ const char * const name , readOptions * readOpts ,
416455 tagPrintOptions * printOpts , struct canonWorkArea * canon )
417456{
418- tagFileInfo info ;
419457 tagEntry entry ;
420458 int err = 0 ;
421- tagFile * const file = openTags (TagFileName , & info );
422- if (file == NULL || !info .status .opened )
459+ tagFileX * const fileX = openTags (inputSpec );
460+ if (fileX -> tagFile == NULL || !fileX -> info .status .opened )
423461 {
424462 fprintf (stderr , "%s: cannot open tag file: %s: %s\n" ,
425- ProgramName , tagsStrerror (info .status .error_number ), TagFileName );
426- if ( file )
427- tagsClose ( file );
463+ ProgramName , tagsStrerror (fileX -> info .status .error_number ),
464+ fileX -> fileName );
465+ deleteTagFileX ( fileX );
428466 exit (1 );
429467 }
430468
431469 if (canon && canon -> cacheTable == NULL )
432- canon -> cacheTable = makeCanonFnameCacheTable (file , canon -> absoluteOnly );
470+ canon -> cacheTable = makeCanonFnameCacheTable (fileX , canon -> absoluteOnly );
433471
434472 if (printOpts -> escaping )
435473 {
436474 printOpts -> escapingInputField = 0 ;
437- if (hasPsuedoTag (file , "!_TAG_OUTPUT_MODE" , "u-ctags" )
438- && hasPsuedoTag (file , "!_TAG_OUTPUT_FILESEP" , "slash" ))
475+ if (hasPsuedoTag (fileX -> tagFile , "!_TAG_OUTPUT_MODE" , "u-ctags" )
476+ && hasPsuedoTag (fileX -> tagFile , "!_TAG_OUTPUT_FILESEP" , "slash" ))
439477 printOpts -> escapingInputField = 1 ;
440478 }
441479
442480 if (readOpts -> sortOverride )
443481 {
444- if (tagsSetSortType (file , readOpts -> sortMethod ) != TagSuccess )
482+ if (tagsSetSortType (fileX -> tagFile , readOpts -> sortMethod ) != TagSuccess )
445483 {
446- err = tagsGetErrno (file );
484+ err = tagsGetErrno (fileX -> tagFile );
447485 fprintf (stderr , "%s: cannot set sort type to %d: %s\n" ,
448486 ProgramName ,
449487 readOpts -> sortMethod ,
@@ -453,59 +491,57 @@ static void findTag (const char *const name, readOptions *readOpts,
453491 }
454492 if (debugMode )
455493 fprintf (stderr , "%s: searching for \"%s\" in \"%s\"\n" ,
456- ProgramName , name , TagFileName );
457- if (tagsFind (file , & entry , name , readOpts -> matchOpts ) == TagSuccess )
458- walkTags (file , & entry , tagsFindNext ,
494+ ProgramName , name , fileX -> fileName );
495+ if (tagsFind (fileX -> tagFile , & entry , name , readOpts -> matchOpts ) == TagSuccess )
496+ walkTags (fileX -> tagFile , & entry , tagsFindNext ,
459497#ifdef READTAGS_DSL
460498 Formatter ? printTagWithFormatter :
461499#endif
462500 printTag , printOpts ,
463501 canon );
464- else if ((err = tagsGetErrno (file )) != 0 )
502+ else if ((err = tagsGetErrno (fileX -> tagFile )) != 0 )
465503 {
466504 fprintf (stderr , "%s: error in tagsFind(): %s\n" ,
467505 ProgramName ,
468506 tagsStrerror (err ));
469507 exit (1 );
470508 }
471- tagsClose ( file );
509+ deleteTagFileX ( fileX );
472510}
473511
474- static void listTags (int pseudoTags , tagPrintOptions * printOpts ,
512+ static void listTags (struct inputSpec * inputSpec , int pseudoTags , tagPrintOptions * printOpts ,
475513 struct canonWorkArea * canon )
476514{
477- tagFileInfo info ;
478515 tagEntry entry ;
479516 int err = 0 ;
480- tagFile * const file = openTags (TagFileName , & info );
481- if (file == NULL || !info .status .opened )
517+ tagFileX * const fileX = openTags (inputSpec );
518+ if (fileX -> tagFile == NULL || !fileX -> info .status .opened )
482519 {
483520 fprintf (stderr , "%s: cannot open tag file: %s: %s\n" ,
484521 ProgramName ,
485- tagsStrerror (info .status .error_number ),
486- TagFileName );
487- if (file )
488- tagsClose (file );
522+ tagsStrerror (fileX -> info .status .error_number ),
523+ fileX -> fileName );
524+ deleteTagFileX (fileX );
489525 exit (1 );
490526 }
491527
492528 if (canon && canon -> cacheTable == NULL )
493- canon -> cacheTable = makeCanonFnameCacheTable (file , canon -> absoluteOnly );
529+ canon -> cacheTable = makeCanonFnameCacheTable (fileX , canon -> absoluteOnly );
494530
495531 if (printOpts -> escaping )
496532 {
497533 printOpts -> escapingInputField = 0 ;
498- if (hasPsuedoTag (file , "!_TAG_OUTPUT_MODE" , "u-ctags" )
499- && hasPsuedoTag (file , "!_TAG_OUTPUT_FILESEP" , "slash" ))
534+ if (hasPsuedoTag (fileX -> tagFile , "!_TAG_OUTPUT_MODE" , "u-ctags" )
535+ && hasPsuedoTag (fileX -> tagFile , "!_TAG_OUTPUT_FILESEP" , "slash" ))
500536 printOpts -> escapingInputField = 1 ;
501537 }
502538
503539 if (pseudoTags )
504540 {
505- if (tagsFirstPseudoTag (file , & entry ) == TagSuccess )
506- walkTags (file , & entry , tagsNextPseudoTag , printPseudoTag , printOpts ,
541+ if (tagsFirstPseudoTag (fileX -> tagFile , & entry ) == TagSuccess )
542+ walkTags (fileX -> tagFile , & entry , tagsNextPseudoTag , printPseudoTag , printOpts ,
507543 canon );
508- else if ((err = tagsGetErrno (file )) != 0 )
544+ else if ((err = tagsGetErrno (fileX -> tagFile )) != 0 )
509545 {
510546 fprintf (stderr , "%s: error in tagsFirstPseudoTag(): %s\n" ,
511547 ProgramName ,
@@ -515,22 +551,22 @@ static void listTags (int pseudoTags, tagPrintOptions *printOpts,
515551 }
516552 else
517553 {
518- if (tagsFirst (file , & entry ) == TagSuccess )
519- walkTags (file , & entry , tagsNext ,
554+ if (tagsFirst (fileX -> tagFile , & entry ) == TagSuccess )
555+ walkTags (fileX -> tagFile , & entry , tagsNext ,
520556#ifdef READTAGS_DSL
521557 Formatter ? printTagWithFormatter :
522558#endif
523559 printTag , printOpts ,
524560 canon );
525- else if ((err = tagsGetErrno (file )) != 0 )
561+ else if ((err = tagsGetErrno (fileX -> tagFile )) != 0 )
526562 {
527563 fprintf (stderr , "%s: error in tagsFirst(): %s\n" ,
528564 ProgramName ,
529565 tagsStrerror (err ));
530566 exit (1 );
531567 }
532568 }
533- tagsClose ( file );
569+ deleteTagFileX ( fileX );
534570}
535571
536572static const char * const Usage =
@@ -666,6 +702,10 @@ extern int main (int argc, char **argv)
666702
667703 tagPrintOptions printOpts ;
668704 readOptions readOpts ;
705+ struct inputSpec inputSpec = {
706+ .tagFileName = "tags" ,
707+ .tempFileName = NULL ,
708+ };
669709
670710 memset (& printOpts , 0 , sizeof (printOpts ));
671711 memset (& readOpts , 0 , sizeof (readOpts ));
@@ -694,7 +734,7 @@ extern int main (int argc, char **argv)
694734 {
695735 if (canon )
696736 canon -> ptags = 0 ;
697- findTag (arg , & readOpts , & printOpts , canon );
737+ findTag (& inputSpec , arg , & readOpts , & printOpts , canon );
698738 actionSupplied = 1 ;
699739 }
700740 else if (arg [0 ] == '-' && arg [1 ] == '\0' )
@@ -709,7 +749,7 @@ extern int main (int argc, char **argv)
709749 {
710750 if (canon )
711751 canon -> ptags = 1 ;
712- listTags (1 , & printOpts , canon );
752+ listTags (& inputSpec , 1 , & printOpts , canon );
713753 if (optname [0 ] == 'l' )
714754 actionSupplied = 1 ;
715755 }
@@ -757,15 +797,15 @@ extern int main (int argc, char **argv)
757797 {
758798 if (canon )
759799 canon -> ptags = 0 ;
760- listTags (0 , & printOpts , canon );
800+ listTags (& inputSpec , 0 , & printOpts , canon );
761801 actionSupplied = 1 ;
762802 }
763803 else if (strcmp (optname , "line - number ") == 0 )
764804 printOpts .lineNumber = 1 ;
765805 else if (strcmp (optname , "tag - file ") == 0 )
766806 {
767807 if (i + 1 < argc )
768- TagFileName = argv [++ i ];
808+ inputSpec . tagFileName = argv [++ i ];
769809 else
770810 printUsage (stderr , 1 );
771811 }
@@ -862,7 +902,7 @@ extern int main (int argc, char **argv)
862902 case 'P' :
863903 if (canon )
864904 canon -> ptags = 1 ;
865- listTags (1 , & printOpts , canon );
905+ listTags (& inputSpec , 1 , & printOpts , canon );
866906 if (arg [j ] == 'D' )
867907 actionSupplied = 1 ;
868908 break ;
@@ -892,18 +932,18 @@ extern int main (int argc, char **argv)
892932 case 'l' :
893933 if (canon )
894934 canon -> ptags = 0 ;
895- listTags (0 , & printOpts , canon );
935+ listTags (& inputSpec , 0 , & printOpts , canon );
896936 actionSupplied = 1 ;
897937 break ;
898938 case 'n' : printOpts .lineNumber = 1 ; break ;
899939 case 't' :
900940 if (arg [j + 1 ] != '\0' )
901941 {
902- TagFileName = arg + j + 1 ;
903- j += strlen (TagFileName );
942+ inputSpec . tagFileName = arg + j + 1 ;
943+ j += strlen (inputSpec . tagFileName );
904944 }
905945 else if (i + 1 < argc )
906- TagFileName = argv [++ i ];
946+ inputSpec . tagFileName = argv [++ i ];
907947 else
908948 printUsage (stderr , 1 );
909949 break ;
@@ -976,5 +1016,11 @@ extern int main (int argc, char **argv)
9761016 if (canon -> cacheTable )
9771017 canonFnameCacheTableDelete (canon -> cacheTable );
9781018 }
1019+
1020+ if (inputSpec .tempFileName )
1021+ {
1022+ remove (inputSpec .tempFileName );
1023+ eFree (inputSpec .tempFileName );
1024+ }
9791025 return 0 ;
9801026}
0 commit comments