69 |
static void put_lines(char *, struct dup_entry *, int); |
static void put_lines(char *, struct dup_entry *, int); |
70 |
int main(int, char **); |
int main(int, char **); |
71 |
int incremental(const char *, const char *); |
int incremental(const char *, const char *); |
72 |
void updatetags(const char *, const char *, IDSET *, STRBUF *, int, int); |
void updatetags(const char *, const char *, IDSET *, STRBUF *, int); |
73 |
void createtags(const char *, const char *, int); |
void createtags(const char *, const char *, int); |
74 |
int printconf(const char *); |
int printconf(const char *); |
75 |
void set_base_directory(const char *, const char *); |
void set_base_directory(const char *, const char *); |
619 |
/* |
/* |
620 |
* create GTAGS, GRTAGS and GSYMS |
* create GTAGS, GRTAGS and GSYMS |
621 |
*/ |
*/ |
|
total = 0; /* counting file */ |
|
622 |
for (db = GTAGS; db < GTAGLIM; db++) { |
for (db = GTAGS; db < GTAGLIM; db++) { |
623 |
|
|
624 |
if (oflag && db == GSYMS) |
if (oflag && db == GSYMS) |
700 |
STRBUF *deletelist = strbuf_open(0); |
STRBUF *deletelist = strbuf_open(0); |
701 |
IDSET *deleteset; |
IDSET *deleteset; |
702 |
int updated = 0; |
int updated = 0; |
|
int addtotal = 0; |
|
703 |
const char *path; |
const char *path; |
704 |
|
|
705 |
if (vflag) { |
if (vflag) { |
724 |
find_open_filelist(file_list, root); |
find_open_filelist(file_list, root); |
725 |
else |
else |
726 |
find_open(NULL); |
find_open(NULL); |
727 |
|
total = 0; |
728 |
while ((path = find_read()) != NULL) { |
while ((path = find_read()) != NULL) { |
729 |
const char *fid; |
const char *fid; |
730 |
|
|
735 |
die("stat failed '%s'.", path); |
die("stat failed '%s'.", path); |
736 |
if ((fid = gpath_path2fid(path)) == NULL) { |
if ((fid = gpath_path2fid(path)) == NULL) { |
737 |
strbuf_puts0(addlist, path); |
strbuf_puts0(addlist, path); |
738 |
addtotal++; |
total++; |
739 |
} else if (gtags_mtime < statp.st_mtime) { |
} else if (gtags_mtime < statp.st_mtime) { |
740 |
strbuf_puts0(addlist, path); |
strbuf_puts0(addlist, path); |
741 |
addtotal++; |
total++; |
742 |
idset_add(deleteset, atoi(fid)); |
idset_add(deleteset, atoi(fid)); |
743 |
} |
} |
744 |
} |
} |
778 |
continue; |
continue; |
779 |
if (vflag) |
if (vflag) |
780 |
fprintf(stderr, "[%s] Updating '%s'.\n", now(), dbname(db)); |
fprintf(stderr, "[%s] Updating '%s'.\n", now(), dbname(db)); |
781 |
updatetags(dbpath, root, deleteset, addlist, addtotal, db); |
updatetags(dbpath, root, deleteset, addlist, db); |
782 |
} |
} |
783 |
} |
} |
784 |
if (strbuf_getlen(deletelist) > 0) { |
if (strbuf_getlen(deletelist) > 0) { |
825 |
* i) root root directory of source tree |
* i) root root directory of source tree |
826 |
* i) deleteset bit array of fid of deleted or modified files |
* i) deleteset bit array of fid of deleted or modified files |
827 |
* i) addlist \0 separated list of added or modified files |
* i) addlist \0 separated list of added or modified files |
|
* i) addtotal number of files in addlist |
|
828 |
* i) db GTAGS, GRTAGS, GSYMS |
* i) db GTAGS, GRTAGS, GSYMS |
829 |
*/ |
*/ |
830 |
|
static void |
831 |
|
verbose_updatetags(char *path, int seqno, int skip) |
832 |
|
{ |
833 |
|
if (total) |
834 |
|
fprintf(stderr, " [%d/%d]", seqno, total); |
835 |
|
else |
836 |
|
fprintf(stderr, " [%d]", seqno); |
837 |
|
fprintf(stderr, " adding tags of %s", path); |
838 |
|
if (skip) |
839 |
|
fprintf(stderr, " (skipped)"); |
840 |
|
fputc('\n', stderr); |
841 |
|
} |
842 |
void |
void |
843 |
updatetags(const char *dbpath, const char *root, IDSET *deleteset, STRBUF *addlist, int addtotal, int db) |
updatetags(const char *dbpath, const char *root, IDSET *deleteset, STRBUF *addlist, int db) |
844 |
{ |
{ |
845 |
GTOP *gtop; |
GTOP *gtop; |
846 |
STRBUF *comline = strbuf_open(0); |
STRBUF *comline = strbuf_open(0); |
847 |
int gflags; |
int flags; |
848 |
int path_list_max; |
int seqno; |
|
int arg_count = 0; |
|
849 |
|
|
850 |
/* |
/* |
851 |
* GTAGS needed to make GRTAGS. |
* GTAGS needed to make GRTAGS. |
858 |
*/ |
*/ |
859 |
if (!getconfs(dbname(db), comline)) |
if (!getconfs(dbname(db), comline)) |
860 |
die("cannot get tag command. (%s)", dbname(db)); |
die("cannot get tag command. (%s)", dbname(db)); |
|
/* |
|
|
* determine the maximum length of the list of paths. |
|
|
*/ |
|
|
path_list_max = exec_line_limit(strbuf_getlen(comline)); |
|
|
|
|
861 |
gtop = gtags_open(dbpath, root, db, GTAGS_MODIFY, 0); |
gtop = gtags_open(dbpath, root, db, GTAGS_MODIFY, 0); |
862 |
if (vflag) { |
if (vflag) { |
863 |
char fid[32]; |
char fid[32]; |
864 |
const char *path; |
const char *path; |
|
int seqno = 1; |
|
865 |
int total = idset_count(deleteset); |
int total = idset_count(deleteset); |
866 |
int i; |
int i; |
867 |
|
|
868 |
|
seqno = 1; |
869 |
for (i = 0; i < deleteset->max; i++) { |
for (i = 0; i < deleteset->max; i++) { |
870 |
if (idset_contains(deleteset, i)) { |
if (idset_contains(deleteset, i)) { |
871 |
snprintf(fid, sizeof(fid), "%d", i); |
snprintf(fid, sizeof(fid), "%d", i); |
878 |
} |
} |
879 |
if (deleteset->max > 0) |
if (deleteset->max > 0) |
880 |
gtags_delete(gtop, deleteset); |
gtags_delete(gtop, deleteset); |
881 |
gflags = 0; |
flags = 0; |
882 |
if (extractmethod) |
if (extractmethod) |
883 |
gflags |= GTAGS_EXTRACTMETHOD; |
flags |= GTAGS_EXTRACTMETHOD; |
884 |
if (debug) |
if (debug) |
885 |
gflags |= GTAGS_DEBUG; |
flags |= GTAGS_DEBUG; |
886 |
/* |
/* |
887 |
* If the --max-args option is not specified, we pass the parser |
* If the --max-args option is not specified, we pass the parser |
888 |
* the source file as a lot as possible to decrease the invoking |
* the source file as a lot as possible to decrease the invoking |
889 |
* frequency of the parser. |
* frequency of the parser. |
890 |
*/ |
*/ |
891 |
{ |
{ |
892 |
STRBUF *path_list = strbuf_open(0); |
XARGS *xp; |
893 |
const char *path = strbuf_value(addlist); |
char *ctags_x; |
894 |
const char *end = path + strbuf_getlen(addlist); |
char tag[MAXTOKEN], *p; |
|
int seqno = 1; |
|
|
|
|
|
while (path < end) { |
|
|
int pathlen = strlen(path); |
|
895 |
|
|
896 |
if (vflag) |
xp = xargs_open_with_strbuf(strbuf_value(comline), max_args, addlist); |
897 |
fprintf(stderr, " [%d/%d] adding tags of %s\n", seqno++, addtotal, path + 2); |
xp->put_gpath = 1; |
898 |
|
if (vflag) |
899 |
|
xp->verbose = verbose_updatetags; |
900 |
|
if (db == GSYMS) |
901 |
|
xp->skip_assembly = 1; |
902 |
|
while ((ctags_x = xargs_read(xp)) != NULL) { |
903 |
|
strlimcpy(tag, strmake(ctags_x, " \t"), sizeof(tag)); |
904 |
/* |
/* |
905 |
* Execute parser when path name collects enough. |
* extract method when class method definition. |
906 |
* Though the path_list is \0 separated list of path, |
* |
907 |
* we can think its length equals to the length of |
* Ex: Class::method(...) |
908 |
* argument string because each \0 can be replaced |
* |
909 |
* with a blank. |
* key = 'method' |
910 |
|
* data = 'Class::method 103 ./class.cpp ...' |
911 |
*/ |
*/ |
912 |
if (strbuf_getlen(path_list)) { |
p = tag; |
913 |
if (path_list_max == 0 || |
if (flags & GTAGS_EXTRACTMETHOD) { |
914 |
(max_args > 0 && arg_count >= max_args) || |
if ((p = locatestring(tag, ".", MATCH_LAST)) != NULL) |
915 |
strbuf_getlen(path_list) + pathlen > path_list_max) |
p++; |
916 |
{ |
else if ((p = locatestring(tag, "::", MATCH_LAST)) != NULL) |
917 |
gtags_add(gtop, strbuf_value(comline), path_list, gflags); |
p += 2; |
918 |
strbuf_reset(path_list); |
else |
919 |
arg_count = 0; |
p = tag; |
|
} |
|
920 |
} |
} |
921 |
/* |
gtags_put(gtop, p, ctags_x); |
922 |
* Add a path to the path list. |
} |
923 |
*/ |
total = xargs_close(xp); |
|
strbuf_puts0(path_list, path); |
|
|
path += pathlen + 1; |
|
|
arg_count++; |
|
|
} |
|
|
if (strbuf_getlen(path_list)) |
|
|
gtags_add(gtop, strbuf_value(comline), path_list, gflags); |
|
|
strbuf_close(path_list); |
|
924 |
} |
} |
|
|
|
925 |
gtags_close(gtop); |
gtags_close(gtop); |
926 |
strbuf_close(comline); |
strbuf_close(comline); |
927 |
} |
} |
932 |
* i) root root directory of source tree |
* i) root root directory of source tree |
933 |
* i) db GTAGS, GRTAGS, GSYMS |
* i) db GTAGS, GRTAGS, GSYMS |
934 |
*/ |
*/ |
935 |
|
static void |
936 |
|
verbose_createtags(char *path, int seqno, int skip) |
937 |
|
{ |
938 |
|
if (total) |
939 |
|
fprintf(stderr, " [%d/%d]", seqno, total); |
940 |
|
else |
941 |
|
fprintf(stderr, " [%d]", seqno); |
942 |
|
fprintf(stderr, " extracting tags of %s", path); |
943 |
|
if (skip) |
944 |
|
fprintf(stderr, " (skipped)"); |
945 |
|
fputc('\n', stderr); |
946 |
|
} |
947 |
void |
void |
948 |
createtags(const char *dbpath, const char *root, int db) |
createtags(const char *dbpath, const char *root, int db) |
949 |
{ |
{ |
|
const char *path; |
|
950 |
GTOP *gtop; |
GTOP *gtop; |
951 |
int flags, gflags; |
int flags; |
952 |
|
XARGS *xp; |
953 |
|
char *ctags_x; |
954 |
STRBUF *comline = strbuf_open(0); |
STRBUF *comline = strbuf_open(0); |
|
int count = 0; |
|
|
int arg_count = 0; |
|
955 |
STRBUF *path_list = strbuf_open(MAXPATHLEN); |
STRBUF *path_list = strbuf_open(MAXPATHLEN); |
|
int path_list_max; |
|
956 |
|
|
957 |
/* |
/* |
958 |
* get tag command. |
* get tag command. |
964 |
*/ |
*/ |
965 |
if (db == GRTAGS && !test("f", makepath(dbpath, dbname(GTAGS), NULL))) |
if (db == GRTAGS && !test("f", makepath(dbpath, dbname(GTAGS), NULL))) |
966 |
die("GTAGS needed to create GRTAGS."); |
die("GTAGS needed to create GRTAGS."); |
|
|
|
|
/* |
|
|
* determine the maximum length of the list of paths. |
|
|
*/ |
|
|
path_list_max = exec_line_limit(strbuf_getlen(comline)); |
|
|
|
|
|
flags = 0; |
|
967 |
/* |
/* |
968 |
* Compact format: |
* Compact format: |
969 |
* |
* |
973 |
* Ths -cc is undocumented. |
* Ths -cc is undocumented. |
974 |
* In the future, it may become the standard format of GLOBAL. |
* In the future, it may become the standard format of GLOBAL. |
975 |
*/ |
*/ |
976 |
|
flags = 0; |
977 |
if (cflag) { |
if (cflag) { |
978 |
flags |= GTAGS_PATHINDEX; |
flags |= GTAGS_PATHINDEX; |
979 |
if (cflag == 1) |
if (cflag == 1) |
982 |
if (vflag > 1) |
if (vflag > 1) |
983 |
fprintf(stderr, " using tag command '%s <path>'.\n", strbuf_value(comline)); |
fprintf(stderr, " using tag command '%s <path>'.\n", strbuf_value(comline)); |
984 |
gtop = gtags_open(dbpath, root, db, GTAGS_CREATE, flags); |
gtop = gtags_open(dbpath, root, db, GTAGS_CREATE, flags); |
985 |
gflags = 0; |
/* |
986 |
|
* Set flags. |
987 |
|
*/ |
988 |
|
gtop->flags = 0; |
989 |
if (extractmethod) |
if (extractmethod) |
990 |
gflags |= GTAGS_EXTRACTMETHOD; |
gtop->flags |= GTAGS_EXTRACTMETHOD; |
991 |
if (debug) |
if (debug) |
992 |
gflags |= GTAGS_DEBUG; |
gtop->flags |= GTAGS_DEBUG; |
993 |
|
/* |
994 |
|
* Compact format requires the tag records of the same file are |
995 |
|
* consecutive. |
996 |
|
* |
997 |
|
* We assume that the output of gtags-parser is consecutive for each |
998 |
|
* file. About the other parsers, it is not guaranteed, so we sort it |
999 |
|
* using external sort command (gnusort). |
1000 |
|
*/ |
1001 |
|
if (gtop->format & GTAGS_COMPACT) { |
1002 |
|
if (locatestring(strbuf_value(comline), "gtags-parser", MATCH_FIRST) == NULL) |
1003 |
|
strbuf_puts(comline, "| gnusort -k 3,3"); |
1004 |
|
} |
1005 |
/* |
/* |
1006 |
* If the --max-args option is not specified, we pass the parser |
* If the --max-args option is not specified, we pass the parser |
1007 |
* the source file as a lot as possible to decrease the invoking |
* the source file as a lot as possible to decrease the invoking |
1011 |
find_open_filelist(file_list, root); |
find_open_filelist(file_list, root); |
1012 |
else |
else |
1013 |
find_open(NULL); |
find_open(NULL); |
1014 |
while ((path = find_read()) != NULL) { |
/* |
1015 |
int skip = 0; |
* Add tags. |
1016 |
|
*/ |
1017 |
|
xp = xargs_open_with_find(strbuf_value(comline), max_args); |
1018 |
|
xp->put_gpath = 1; |
1019 |
|
if (vflag) |
1020 |
|
xp->verbose = verbose_createtags; |
1021 |
|
if (db == GSYMS) |
1022 |
|
xp->skip_assembly = 1; |
1023 |
|
while ((ctags_x = xargs_read(xp)) != NULL) { |
1024 |
|
char tag[MAXTOKEN], *p; |
1025 |
|
|
1026 |
/* a blank at the head of path means 'NOT SOURCE'. */ |
strlimcpy(tag, strmake(ctags_x, " \t"), sizeof(tag)); |
|
if (*path == ' ') |
|
|
continue; |
|
|
count++; |
|
1027 |
/* |
/* |
1028 |
* GSYMS doesn't treat asembler. |
* extract method when class method definition. |
1029 |
|
* |
1030 |
|
* Ex: Class::method(...) |
1031 |
|
* |
1032 |
|
* key = 'method' |
1033 |
|
* data = 'Class::method 103 ./class.cpp ...' |
1034 |
*/ |
*/ |
1035 |
if (db == GSYMS) { |
p = tag; |
1036 |
if (locatestring(path, ".s", MATCH_AT_LAST) != NULL || |
if (gtop->flags & GTAGS_EXTRACTMETHOD) { |
1037 |
locatestring(path, ".S", MATCH_AT_LAST) != NULL) |
if ((p = locatestring(tag, ".", MATCH_LAST)) != NULL) |
1038 |
skip = 1; |
p++; |
1039 |
} |
else if ((p = locatestring(tag, "::", MATCH_LAST)) != NULL) |
1040 |
if (vflag) { |
p += 2; |
|
if (total) |
|
|
fprintf(stderr, " [%d/%d]", count, total); |
|
1041 |
else |
else |
1042 |
fprintf(stderr, " [%d]", count); |
p = tag; |
|
fprintf(stderr, " extracting tags of %s", path + 2); |
|
|
if (skip) |
|
|
fprintf(stderr, " (skipped)"); |
|
|
fputc('\n', stderr); |
|
|
} |
|
|
if (skip) |
|
|
continue; |
|
|
/* |
|
|
* Execute parser when path name collects enough. |
|
|
* Though the path_list is \0 separated list of string, |
|
|
* we can think its length equals to the length of |
|
|
* argument string because each \0 can be replaced |
|
|
* with a blank. |
|
|
*/ |
|
|
if (strbuf_getlen(path_list)) { |
|
|
if (path_list_max == 0 || |
|
|
(max_args > 0 && arg_count >= max_args) || |
|
|
strbuf_getlen(path_list) + strlen(path) > path_list_max) |
|
|
{ |
|
|
gtags_add(gtop, strbuf_value(comline), path_list, gflags); |
|
|
strbuf_reset(path_list); |
|
|
arg_count = 0; |
|
|
} |
|
1043 |
} |
} |
1044 |
/* |
gtags_put(gtop, p, ctags_x); |
|
* Add a path to path_list. |
|
|
*/ |
|
|
strbuf_puts0(path_list, path); |
|
|
arg_count++; |
|
1045 |
} |
} |
1046 |
if (strbuf_getlen(path_list)) |
total = xargs_close(xp); |
|
gtags_add(gtop, strbuf_value(comline), path_list, gflags); |
|
|
total = count; /* save total count */ |
|
1047 |
find_close(); |
find_close(); |
1048 |
gtags_close(gtop); |
gtags_close(gtop); |
1049 |
strbuf_close(comline); |
strbuf_close(comline); |