66 |
int match(const char *, const char *); |
int match(const char *, const char *); |
67 |
int main(int, char **); |
int main(int, char **); |
68 |
int incremental(const char *, const char *); |
int incremental(const char *, const char *); |
69 |
void updatetags(const char *, const char *, const unsigned char *, int, STRBUF *, int); |
void updatetags(const char *, const char *, const char *, int); |
70 |
|
int incremental_optimized_for_speed(const char *, const char *); |
71 |
|
void updatetags_optimized_for_speed(const char *, const char *, const unsigned char *, int, STRBUF *, int); |
72 |
void createtags(const char *, const char *, int); |
void createtags(const char *, const char *, int); |
73 |
int printconf(const char *); |
int printconf(const char *); |
74 |
void set_base_directory(const char *, const char *); |
void set_base_directory(const char *, const char *); |
592 |
*/ |
*/ |
593 |
if (!test("f", makepath(dbpath, dbname(GPATH), NULL))) |
if (!test("f", makepath(dbpath, dbname(GPATH), NULL))) |
594 |
die("Old version tag file found. Please remake it."); |
die("Old version tag file found. Please remake it."); |
595 |
(void)incremental(dbpath, cwd); |
if (vflag) |
596 |
|
(void)incremental(dbpath, cwd); |
597 |
|
else |
598 |
|
(void)incremental_optimized_for_speed(dbpath, cwd); |
599 |
exit(0); |
exit(0); |
600 |
} |
} |
601 |
/* |
/* |
684 |
{ |
{ |
685 |
struct stat statp; |
struct stat statp; |
686 |
time_t gtags_mtime; |
time_t gtags_mtime; |
687 |
STRBUF *extractlist = strbuf_open(0); |
STRBUF *addlist = strbuf_open(0); |
688 |
|
STRBUF *updatelist = strbuf_open(0); |
689 |
STRBUF *deletelist = strbuf_open(0); |
STRBUF *deletelist = strbuf_open(0); |
|
unsigned char *fidset; |
|
|
int max_fid = 0; |
|
690 |
int updated = 0; |
int updated = 0; |
691 |
const char *path; |
const char *path; |
692 |
|
|
704 |
|
|
705 |
if (gpath_open(dbpath, 0) < 0) |
if (gpath_open(dbpath, 0) < 0) |
706 |
die("GPATH not found."); |
die("GPATH not found."); |
707 |
|
/* |
708 |
|
* make add list and update list. |
709 |
|
*/ |
710 |
|
for (find_open(NULL); (path = find_read()) != NULL; ) { |
711 |
|
/* a blank at the head of path means 'NOT SOURCE'. */ |
712 |
|
if (*path == ' ') |
713 |
|
continue; |
714 |
|
if (stat(path, &statp) < 0) |
715 |
|
die("stat failed '%s'.", path); |
716 |
|
if (!gpath_path2fid(path)) |
717 |
|
strbuf_puts0(addlist, path); |
718 |
|
else if (gtags_mtime < statp.st_mtime) |
719 |
|
strbuf_puts0(updatelist, path); |
720 |
|
} |
721 |
|
find_close(); |
722 |
|
/* |
723 |
|
* make delete list. |
724 |
|
*/ |
725 |
|
{ |
726 |
|
char fid[32]; |
727 |
|
int i, limit = gpath_nextkey(); |
728 |
|
|
729 |
|
for (i = 1; i < limit; i++) { |
730 |
|
snprintf(fid, sizeof(fid), "%d", i); |
731 |
|
if ((path = gpath_fid2path(fid)) == NULL) |
732 |
|
continue; |
733 |
|
if (!test("f", path)) |
734 |
|
strbuf_puts0(deletelist, path); |
735 |
|
} |
736 |
|
} |
737 |
|
gpath_close(); |
738 |
|
if (strbuf_getlen(addlist) + strbuf_getlen(deletelist) + strbuf_getlen(updatelist)) |
739 |
|
updated = 1; |
740 |
|
/* |
741 |
|
* execute updating. |
742 |
|
*/ |
743 |
|
signal_setup(); |
744 |
|
if (strbuf_getlen(updatelist) > 0) { |
745 |
|
const char *start = strbuf_value(updatelist); |
746 |
|
const char *end = start + strbuf_getlen(updatelist); |
747 |
|
const char *p; |
748 |
|
|
749 |
|
for (p = start; p < end; p += strlen(p) + 1) { |
750 |
|
updatetags(dbpath, root, p, 0); |
751 |
|
if (exitflag) |
752 |
|
exit(1); |
753 |
|
} |
754 |
|
updated = 1; |
755 |
|
} |
756 |
|
if (strbuf_getlen(addlist) > 0) { |
757 |
|
const char *start = strbuf_value(addlist); |
758 |
|
const char *end = start + strbuf_getlen(addlist); |
759 |
|
const char *p; |
760 |
|
|
761 |
|
for (p = start; p < end; p += strlen(p) + 1) { |
762 |
|
updatetags(dbpath, root, p, 1); |
763 |
|
if (exitflag) |
764 |
|
exit(1); |
765 |
|
} |
766 |
|
updated = 1; |
767 |
|
} |
768 |
|
if (strbuf_getlen(deletelist) > 0) { |
769 |
|
const char *start = strbuf_value(deletelist); |
770 |
|
const char *end = start + strbuf_getlen(deletelist); |
771 |
|
const char *p; |
772 |
|
|
773 |
|
for (p = start; p < end; p += strlen(p) + 1) { |
774 |
|
updatetags(dbpath, root, p, 2); |
775 |
|
if (exitflag) |
776 |
|
exit(1); |
777 |
|
} |
778 |
|
|
779 |
|
gpath_open(dbpath, 2); |
780 |
|
for (p = start; p < end; p += strlen(p) + 1) { |
781 |
|
if (exitflag) |
782 |
|
break; |
783 |
|
gpath_delete(p); |
784 |
|
} |
785 |
|
gpath_close(); |
786 |
|
updated = 1; |
787 |
|
} |
788 |
|
if (exitflag) |
789 |
|
exit(1); |
790 |
|
if (updated) { |
791 |
|
int db; |
792 |
|
/* |
793 |
|
* Update modification time of tag files |
794 |
|
* because they may have no definitions. |
795 |
|
*/ |
796 |
|
for (db = GTAGS; db < GTAGLIM; db++) |
797 |
|
#ifdef HAVE_UTIMES |
798 |
|
utimes(makepath(dbpath, dbname(db), NULL), NULL); |
799 |
|
#else |
800 |
|
utime(makepath(dbpath, dbname(db), NULL), NULL); |
801 |
|
#endif /* HAVE_UTIMES */ |
802 |
|
} |
803 |
|
if (vflag) { |
804 |
|
if (updated) |
805 |
|
fprintf(stderr, " Global databases have been modified.\n"); |
806 |
|
else |
807 |
|
fprintf(stderr, " Global databases are up to date.\n"); |
808 |
|
fprintf(stderr, "[%s] Done.\n", now()); |
809 |
|
} |
810 |
|
strbuf_close(addlist); |
811 |
|
strbuf_close(deletelist); |
812 |
|
strbuf_close(updatelist); |
813 |
|
return updated; |
814 |
|
} |
815 |
|
/* |
816 |
|
* updatetags: update tag file. |
817 |
|
* |
818 |
|
* i) dbpath directory in which tag file exist |
819 |
|
* i) root root directory of source tree |
820 |
|
* i) path path which should be updated |
821 |
|
* i) type 0:update, 1:add, 2:delete |
822 |
|
*/ |
823 |
|
void |
824 |
|
updatetags(dbpath, root, path, type) |
825 |
|
const char *dbpath; |
826 |
|
const char *root; |
827 |
|
const char *path; |
828 |
|
int type; |
829 |
|
{ |
830 |
|
GTOP *gtop; |
831 |
|
STRBUF *sb = strbuf_open(0); |
832 |
|
int db; |
833 |
|
const char *msg = NULL; |
834 |
|
|
835 |
|
switch (type) { |
836 |
|
case 0: msg = "Updating"; break; |
837 |
|
case 1: msg = "Adding"; break; |
838 |
|
case 2: msg = "Deleting"; break; |
839 |
|
} |
840 |
|
if (vflag) |
841 |
|
fprintf(stderr, " %s tags of %s ...", msg, path + 2); |
842 |
|
for (db = GTAGS; db < GTAGLIM; db++) { |
843 |
|
int gflags = 0; |
844 |
|
|
845 |
|
if (exitflag) |
846 |
|
break; |
847 |
|
/* |
848 |
|
* GTAGS needed at least. |
849 |
|
*/ |
850 |
|
if ((db == GRTAGS || db == GSYMS) && !test("f", makepath(dbpath, dbname(db), NULL))) |
851 |
|
continue; |
852 |
|
/* |
853 |
|
* GTAGS needed to make GRTAGS. |
854 |
|
*/ |
855 |
|
if (db == GRTAGS && !test("f", makepath(dbpath, dbname(GTAGS), NULL))) |
856 |
|
die("GTAGS needed to create GRTAGS."); |
857 |
|
if (vflag) |
858 |
|
fprintf(stderr, "%s", dbname(db)); |
859 |
|
/* |
860 |
|
* get tag command. |
861 |
|
*/ |
862 |
|
strbuf_reset(sb); |
863 |
|
if (!getconfs(dbname(db), sb)) |
864 |
|
die("cannot get tag command. (%s)", dbname(db)); |
865 |
|
gtop = gtags_open(dbpath, root, db, GTAGS_MODIFY, 0); |
866 |
|
if (type != 1) |
867 |
|
gtags_delete(gtop, path); |
868 |
|
if (vflag) |
869 |
|
fprintf(stderr, ".."); |
870 |
|
if (type != 2) { |
871 |
|
if (extractmethod) |
872 |
|
gflags |= GTAGS_EXTRACTMETHOD; |
873 |
|
if (debug) |
874 |
|
gflags |= GTAGS_DEBUG; |
875 |
|
gtags_add(gtop, strbuf_value(sb), path, gflags); |
876 |
|
} |
877 |
|
gtags_close(gtop); |
878 |
|
} |
879 |
|
strbuf_close(sb); |
880 |
|
if (exitflag) |
881 |
|
return; |
882 |
|
if (vflag) |
883 |
|
fprintf(stderr, " Done.\n"); |
884 |
|
} |
885 |
|
/* |
886 |
|
* incremental_optimized_for_speed: incremental update |
887 |
|
* |
888 |
|
* i) dbpath dbpath directory |
889 |
|
* i) root root directory of source tree |
890 |
|
* r) 0: not updated, 1: updated |
891 |
|
*/ |
892 |
|
int |
893 |
|
incremental_optimized_for_speed(dbpath, root) |
894 |
|
const char *dbpath; |
895 |
|
const char *root; |
896 |
|
{ |
897 |
|
struct stat statp; |
898 |
|
time_t gtags_mtime; |
899 |
|
STRBUF *extractlist = strbuf_open(0); |
900 |
|
STRBUF *deletelist = strbuf_open(0); |
901 |
|
unsigned char *fidset; |
902 |
|
int max_fid = 0; |
903 |
|
int updated = 0; |
904 |
|
const char *path; |
905 |
|
|
906 |
|
/* |
907 |
|
* get modified time of GTAGS. |
908 |
|
*/ |
909 |
|
path = makepath(dbpath, dbname(GTAGS), NULL); |
910 |
|
if (stat(path, &statp) < 0) |
911 |
|
die("stat failed '%s'.", path); |
912 |
|
gtags_mtime = statp.st_mtime; |
913 |
|
|
914 |
|
if (gpath_open(dbpath, 0) < 0) |
915 |
|
die("GPATH not found."); |
916 |
fidset = (unsigned char *)calloc((gpath_nextkey() + CHAR_BIT - 1) / CHAR_BIT, 1); |
fidset = (unsigned char *)calloc((gpath_nextkey() + CHAR_BIT - 1) / CHAR_BIT, 1); |
917 |
if (fidset == NULL) |
if (fidset == NULL) |
918 |
die("short of memory."); |
die("short of memory."); |
975 |
if ((db == GRTAGS || db == GSYMS) |
if ((db == GRTAGS || db == GSYMS) |
976 |
&& !test("f", makepath(dbpath, dbname(db), NULL))) |
&& !test("f", makepath(dbpath, dbname(db), NULL))) |
977 |
continue; |
continue; |
978 |
updatetags(dbpath, root, fidset, max_fid, extractlist, db); |
updatetags_optimized_for_speed(dbpath, root, fidset, max_fid, extractlist, db); |
979 |
if (exitflag) |
if (exitflag) |
980 |
exit(1); |
exit(1); |
981 |
} |
} |
1008 |
utime(makepath(dbpath, dbname(db), NULL), NULL); |
utime(makepath(dbpath, dbname(db), NULL), NULL); |
1009 |
#endif /* HAVE_UTIMES */ |
#endif /* HAVE_UTIMES */ |
1010 |
} |
} |
|
if (vflag) { |
|
|
if (updated) |
|
|
fprintf(stderr, " Global databases have been modified.\n"); |
|
|
else |
|
|
fprintf(stderr, " Global databases are up to date.\n"); |
|
|
fprintf(stderr, "[%s] Done.\n", now()); |
|
|
} |
|
1011 |
strbuf_close(extractlist); |
strbuf_close(extractlist); |
1012 |
strbuf_close(deletelist); |
strbuf_close(deletelist); |
1013 |
free(fidset); |
free(fidset); |
1014 |
return updated; |
return updated; |
1015 |
} |
} |
1016 |
/* |
/* |
1017 |
* updatetags: update tag file. |
* updatetags_optimized_for_speed: update tag file. |
1018 |
* |
* |
1019 |
* i) dbpath directory in which tag file exist |
* i) dbpath directory in which tag file exist |
1020 |
* i) root root directory of source tree |
* i) root root directory of source tree |
1024 |
* i) db GTAGS, GRTAGS, GSYMS |
* i) db GTAGS, GRTAGS, GSYMS |
1025 |
*/ |
*/ |
1026 |
void |
void |
1027 |
updatetags(dbpath, root, fidset, max_fid, extractlist, db) |
updatetags_optimized_for_speed(dbpath, root, fidset, max_fid, extractlist, db) |
1028 |
const char *dbpath; |
const char *dbpath; |
1029 |
const char *root; |
const char *root; |
1030 |
const unsigned char *fidset; |
const unsigned char *fidset; |
1039 |
STRBUF *sb = strbuf_open(0); |
STRBUF *sb = strbuf_open(0); |
1040 |
int gflags; |
int gflags; |
1041 |
|
|
|
if (vflag) |
|
|
fprintf(stderr, " Updating '%s'...", dbname(db)); |
|
|
|
|
1042 |
/* |
/* |
1043 |
* GTAGS needed to make GRTAGS. |
* GTAGS needed to make GRTAGS. |
1044 |
*/ |
*/ |
1054 |
|
|
1055 |
gtop = gtags_open(dbpath, root, db, GTAGS_MODIFY, 0); |
gtop = gtags_open(dbpath, root, db, GTAGS_MODIFY, 0); |
1056 |
|
|
1057 |
if (max_fid > 0) { |
if (max_fid > 0) |
|
if (vflag) |
|
|
fputs(" Deleting tags..", stderr); |
|
1058 |
gtags_delete_by_fidset(gtop, fidset, max_fid); |
gtags_delete_by_fidset(gtop, fidset, max_fid); |
|
} |
|
1059 |
|
|
|
if (vflag && strbuf_getlen(extractlist)) |
|
|
fputs(" Adding tags..", stderr); |
|
1060 |
gflags = 0; |
gflags = 0; |
1061 |
if (extractmethod) |
if (extractmethod) |
1062 |
gflags |= GTAGS_EXTRACTMETHOD; |
gflags |= GTAGS_EXTRACTMETHOD; |
1073 |
|
|
1074 |
gtags_close(gtop); |
gtags_close(gtop); |
1075 |
strbuf_close(sb); |
strbuf_close(sb); |
|
if (exitflag) |
|
|
return; |
|
|
if (vflag) |
|
|
fputs(" Done.\n", stderr); |
|
1076 |
} |
} |
1077 |
/* |
/* |
1078 |
* createtags: create tags file |
* createtags: create tags file |