/[global]/global/gtags/gtags.c
ViewVC logotype

Diff of /global/gtags/gtags.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.119 by h-iwamoto, Sun Jul 3 17:38:48 2005 UTC revision 1.120 by h-iwamoto, Tue Jul 5 11:40:47 2005 UTC
# Line 59  Line 59 
59  #include "global.h"  #include "global.h"
60  #include "const.h"  #include "const.h"
61    
62    #if !defined(ARG_MAX) && defined(_SC_ARG_MAX)
63    #define ARG_MAX         sysconf(_SC_ARG_MAX)
64    #endif
65    
66  static void usage(void);  static void usage(void);
67  static void help(void);  static void help(void);
68  void signal_setup(void);  void signal_setup(void);
# Line 66  void onintr(int); Line 70  void onintr(int);
70  int match(const char *, const char *);  int match(const char *, const char *);
71  int main(int, char **);  int main(int, char **);
72  int incremental(const char *, const char *);  int incremental(const char *, const char *);
73  void updatetags(const char *, const char *, const char *, int);  void updatetags(const char *, const char *, const unsigned char *, int, STRBUF *, int);
 int incremental_optimized_for_speed(const char *, const char *);  
 void updatetags_optimized_for_speed(const char *, const char *, const unsigned char *, int, STRBUF *, int);  
74  void createtags(const char *, const char *, int);  void createtags(const char *, const char *, int);
75  int printconf(const char *);  int printconf(const char *);
76  void set_base_directory(const char *, const char *);  void set_base_directory(const char *, const char *);
# Line 97  int gtagslabel; Line 99  int gtagslabel;
99  int other_files;  int other_files;
100  int debug;  int debug;
101  int secure_mode;  int secure_mode;
102    int noxargs;
103  const char *extra_options;  const char *extra_options;
104  const char *info_string;  const char *info_string;
105  const char *sed_string;  const char *sed_string;
# Line 138  static struct option const long_options[ Line 141  static struct option const long_options[
141          {"gtagsconf", required_argument, &gtagsconf, 1},          {"gtagsconf", required_argument, &gtagsconf, 1},
142          {"gtagslabel", required_argument, &gtagslabel, 1},          {"gtagslabel", required_argument, &gtagslabel, 1},
143          {"idutils", no_argument, NULL, 'I'},          {"idutils", no_argument, NULL, 'I'},
144            {"noxargs", no_argument, &noxargs, 1},
145          {"other", no_argument, &other_files, 1},          {"other", no_argument, &other_files, 1},
146          {"relative", no_argument, &do_relative, 1},          {"relative", no_argument, &do_relative, 1},
147          {"secure", no_argument, &secure_mode, 1},          {"secure", no_argument, &secure_mode, 1},
# Line 592  main(argc, argv) Line 596  main(argc, argv)
596                   */                   */
597                  if (!test("f", makepath(dbpath, dbname(GPATH), NULL)))                  if (!test("f", makepath(dbpath, dbname(GPATH), NULL)))
598                          die("Old version tag file found. Please remake it.");                          die("Old version tag file found. Please remake it.");
599                  if (vflag)                  (void)incremental(dbpath, cwd);
                         (void)incremental(dbpath, cwd);  
                 else  
                         (void)incremental_optimized_for_speed(dbpath, cwd);  
600                  exit(0);                  exit(0);
601          }          }
602          /*          /*
# Line 684  incremental(dbpath, root) Line 685  incremental(dbpath, root)
685  {  {
686          struct stat statp;          struct stat statp;
687          time_t gtags_mtime;          time_t gtags_mtime;
688          STRBUF *addlist = strbuf_open(0);          STRBUF *extractlist = strbuf_open(0);
         STRBUF *updatelist = strbuf_open(0);  
689          STRBUF *deletelist = strbuf_open(0);          STRBUF *deletelist = strbuf_open(0);
690            unsigned char *fidset;
691            int max_fid = 0;
692          int updated = 0;          int updated = 0;
693          const char *path;          const char *path;
694    
# Line 704  incremental(dbpath, root) Line 706  incremental(dbpath, root)
706    
707          if (gpath_open(dbpath, 0) < 0)          if (gpath_open(dbpath, 0) < 0)
708                  die("GPATH not found.");                  die("GPATH not found.");
         /*  
          * make add list and update list.  
          */  
         for (find_open(NULL); (path = find_read()) != NULL; ) {  
                 /* a blank at the head of path means 'NOT SOURCE'. */  
                 if (*path == ' ')  
                         continue;  
                 if (stat(path, &statp) < 0)  
                         die("stat failed '%s'.", path);  
                 if (!gpath_path2fid(path))  
                         strbuf_puts0(addlist, path);  
                 else if (gtags_mtime < statp.st_mtime)  
                         strbuf_puts0(updatelist, path);  
         }  
         find_close();  
         /*  
          * make delete list.  
          */  
         {  
                 char fid[32];  
                 int i, limit = gpath_nextkey();  
   
                 for (i = 1; i < limit; i++) {  
                         snprintf(fid, sizeof(fid), "%d", i);  
                         if ((path = gpath_fid2path(fid)) == NULL)  
                                 continue;  
                         if (!test("f", path))  
                                 strbuf_puts0(deletelist, path);  
                 }  
         }  
         gpath_close();  
         if (strbuf_getlen(addlist) + strbuf_getlen(deletelist) + strbuf_getlen(updatelist))  
                 updated = 1;  
         /*  
          * execute updating.  
          */  
         signal_setup();  
         if (strbuf_getlen(updatelist) > 0) {  
                 const char *start = strbuf_value(updatelist);  
                 const char *end = start + strbuf_getlen(updatelist);  
                 const char *p;  
   
                 for (p = start; p < end; p += strlen(p) + 1) {  
                         updatetags(dbpath, root, p, 0);  
                         if (exitflag)  
                                 exit(1);  
                 }  
                 updated = 1;  
         }  
         if (strbuf_getlen(addlist) > 0) {  
                 const char *start = strbuf_value(addlist);  
                 const char *end = start + strbuf_getlen(addlist);  
                 const char *p;  
   
                 for (p = start; p < end; p += strlen(p) + 1) {  
                         updatetags(dbpath, root, p, 1);  
                         if (exitflag)  
                                 exit(1);  
                 }  
                 updated = 1;  
         }  
         if (strbuf_getlen(deletelist) > 0) {  
                 const char *start = strbuf_value(deletelist);  
                 const char *end = start + strbuf_getlen(deletelist);  
                 const char *p;  
   
                 for (p = start; p < end; p += strlen(p) + 1) {  
                         updatetags(dbpath, root, p, 2);  
                         if (exitflag)  
                                 exit(1);  
                 }  
   
                 gpath_open(dbpath, 2);  
                 for (p = start; p < end; p += strlen(p) + 1) {  
                         if (exitflag)  
                                 break;  
                         gpath_delete(p);  
                 }  
                 gpath_close();  
                 updated = 1;  
         }  
         if (exitflag)  
                 exit(1);  
         if (updated) {  
                 int db;  
                 /*  
                  * Update modification time of tag files  
                  * because they may have no definitions.  
                  */  
                 for (db = GTAGS; db < GTAGLIM; db++)  
 #ifdef HAVE_UTIMES  
                         utimes(makepath(dbpath, dbname(db), NULL), NULL);  
 #else  
                         utime(makepath(dbpath, dbname(db), NULL), NULL);  
 #endif /* HAVE_UTIMES */  
         }  
         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());  
         }  
         strbuf_close(addlist);  
         strbuf_close(deletelist);  
         strbuf_close(updatelist);  
         return updated;  
 }  
 /*  
  * updatetags: update tag file.  
  *  
  *      i)      dbpath  directory in which tag file exist  
  *      i)      root    root directory of source tree  
  *      i)      path    path which should be updated  
  *      i)      type    0:update, 1:add, 2:delete  
  */  
 void  
 updatetags(dbpath, root, path, type)  
         const char *dbpath;  
         const char *root;  
         const char *path;  
         int type;  
 {  
         GTOP *gtop;  
         STRBUF *sb = strbuf_open(0);  
         int db;  
         const char *msg = NULL;  
   
         switch (type) {  
         case 0: msg = "Updating"; break;  
         case 1: msg = "Adding"; break;  
         case 2: msg = "Deleting"; break;  
         }  
         if (vflag)  
                 fprintf(stderr, " %s tags of %s ...", msg, path + 2);  
         for (db = GTAGS; db < GTAGLIM; db++) {  
                 int gflags = 0;  
   
                 if (exitflag)  
                         break;  
                 /*  
                  * GTAGS needed at least.  
                  */  
                 if ((db == GRTAGS || db == GSYMS) && !test("f", makepath(dbpath, dbname(db), NULL)))  
                         continue;  
                 /*  
                  * GTAGS needed to make GRTAGS.  
                  */  
                 if (db == GRTAGS && !test("f", makepath(dbpath, dbname(GTAGS), NULL)))  
                         die("GTAGS needed to create GRTAGS.");  
                 if (vflag)  
                         fprintf(stderr, "%s", dbname(db));  
                 /*  
                  * get tag command.  
                  */  
                 strbuf_reset(sb);  
                 if (!getconfs(dbname(db), sb))  
                         die("cannot get tag command. (%s)", dbname(db));  
                 gtop = gtags_open(dbpath, root, db, GTAGS_MODIFY, 0);  
                 if (type != 1)  
                         gtags_delete(gtop, path);  
                 if (vflag)  
                         fprintf(stderr, "..");  
                 if (type != 2) {  
                         if (extractmethod)  
                                 gflags |= GTAGS_EXTRACTMETHOD;  
                         if (debug)  
                                 gflags |= GTAGS_DEBUG;  
                         gtags_add(gtop, strbuf_value(sb), path, gflags);  
                 }  
                 gtags_close(gtop);  
         }  
         strbuf_close(sb);  
         if (exitflag)  
                 return;  
         if (vflag)  
                 fprintf(stderr, " Done.\n");  
 }  
 /*  
  * incremental_optimized_for_speed: incremental update  
  *  
  *      i)      dbpath  dbpath directory  
  *      i)      root    root directory of source tree  
  *      r)              0: not updated, 1: updated  
  */  
 int  
 incremental_optimized_for_speed(dbpath, root)  
         const char *dbpath;  
         const char *root;  
 {  
         struct stat statp;  
         time_t gtags_mtime;  
         STRBUF *extractlist = strbuf_open(0);  
         STRBUF *deletelist = strbuf_open(0);  
         unsigned char *fidset;  
         int max_fid = 0;  
         int updated = 0;  
         const char *path;  
   
         /*  
          * get modified time of GTAGS.  
          */  
         path = makepath(dbpath, dbname(GTAGS), NULL);  
         if (stat(path, &statp) < 0)  
                 die("stat failed '%s'.", path);  
         gtags_mtime = statp.st_mtime;  
   
         if (gpath_open(dbpath, 0) < 0)  
                 die("GPATH not found.");  
709          fidset = (unsigned char *)calloc((gpath_nextkey() + CHAR_BIT - 1) / CHAR_BIT, 1);          fidset = (unsigned char *)calloc((gpath_nextkey() + CHAR_BIT - 1) / CHAR_BIT, 1);
710          if (fidset == NULL)          if (fidset == NULL)
711                  die("short of memory.");                  die("short of memory.");
# Line 975  incremental_optimized_for_speed(dbpath, Line 768  incremental_optimized_for_speed(dbpath,
768                          if ((db == GRTAGS || db == GSYMS)                          if ((db == GRTAGS || db == GSYMS)
769                              && !test("f", makepath(dbpath, dbname(db), NULL)))                              && !test("f", makepath(dbpath, dbname(db), NULL)))
770                                  continue;                                  continue;
771                          updatetags_optimized_for_speed(dbpath, root, fidset, max_fid, extractlist, db);                          if (vflag)
772                                    fprintf(stderr, "[%s] Updating '%s'.\n", now(), dbname(db));
773                            updatetags(dbpath, root, fidset, max_fid, extractlist, db);
774                          if (exitflag)                          if (exitflag)
775                                  exit(1);                                  exit(1);
776                  }                  }
# Line 1008  incremental_optimized_for_speed(dbpath, Line 803  incremental_optimized_for_speed(dbpath,
803                          utime(makepath(dbpath, dbname(db), NULL), NULL);                          utime(makepath(dbpath, dbname(db), NULL), NULL);
804  #endif /* HAVE_UTIMES */  #endif /* HAVE_UTIMES */
805          }          }
806            if (vflag) {
807                    if (updated)
808                            fprintf(stderr, " Global databases have been modified.\n");
809                    else
810                            fprintf(stderr, " Global databases are up to date.\n");
811                    fprintf(stderr, "[%s] Done.\n", now());
812            }
813          strbuf_close(extractlist);          strbuf_close(extractlist);
814          strbuf_close(deletelist);          strbuf_close(deletelist);
815          free(fidset);          free(fidset);
816          return updated;          return updated;
817  }  }
818  /*  /*
819   * updatetags_optimized_for_speed: update tag file.   * updatetags: update tag file.
820   *   *
821   *      i)      dbpath          directory in which tag file exist   *      i)      dbpath          directory in which tag file exist
822   *      i)      root            root directory of source tree   *      i)      root            root directory of source tree
# Line 1024  incremental_optimized_for_speed(dbpath, Line 826  incremental_optimized_for_speed(dbpath,
826   *      i)      db              GTAGS, GRTAGS, GSYMS   *      i)      db              GTAGS, GRTAGS, GSYMS
827   */   */
828  void  void
829  updatetags_optimized_for_speed(dbpath, root, fidset, max_fid, extractlist, db)  updatetags(dbpath, root, fidset, max_fid, extractlist, db)
830          const char *dbpath;          const char *dbpath;
831          const char *root;          const char *root;
832          const unsigned char *fidset;          const unsigned char *fidset;
# Line 1033  updatetags_optimized_for_speed(dbpath, r Line 835  updatetags_optimized_for_speed(dbpath, r
835          int db;          int db;
836  {  {
837          GTOP *gtop;          GTOP *gtop;
         const char *path;  
838          const char *comline;          const char *comline;
839          const char *end;          const char *end;
840          STRBUF *sb = strbuf_open(0);          STRBUF *sb = strbuf_open(0);
841          int gflags;          int gflags;
842            STATIC_STRBUF(path_list);
843            int path_list_max;
844            int savec;
845            int pathlen;
846    
847          /*          /*
848           * GTAGS needed to make GRTAGS.           * GTAGS needed to make GRTAGS.
# Line 1052  updatetags_optimized_for_speed(dbpath, r Line 857  updatetags_optimized_for_speed(dbpath, r
857                  die("cannot get tag command. (%s)", dbname(db));                  die("cannot get tag command. (%s)", dbname(db));
858          comline = strbuf_value(sb);          comline = strbuf_value(sb);
859    
860            /*
861             * determine the maximum length of the list of paths.
862             */
863    #ifdef ARG_MAX
864            if (noxargs) {
865                    /* force processing files individually. */
866                    path_list_max = 0;
867            } else {
868                    path_list_max = ARG_MAX;
869                    path_list_max -= 2048;
870                    if (path_list_max > 20 * 1024)
871                            path_list_max = 20 * 1024;
872                    path_list_max -= env_size();
873                    path_list_max -= strbuf_getlen(sb);
874                    path_list_max -= 40;
875                    if (path_list_max < 0)
876                            path_list_max = 0;
877            }
878    #else
879            path_list_max = 0;
880    #endif
881    
882          gtop = gtags_open(dbpath, root, db, GTAGS_MODIFY, 0);          gtop = gtags_open(dbpath, root, db, GTAGS_MODIFY, 0);
883            if (gtop->format & GTAGS_COMPACT) {
884                    /* force processing files individually. */
885                    path_list_max = 0;
886            }
887    
888            if (vflag) {
889                    char fid[32];
890                    const char *path;
891                    int i;
892    
893                    for (i = 0; i < max_fid; i++) {
894                            if (fidset[i / CHAR_BIT] & (1 << (i % CHAR_BIT))) {
895                                    snprintf(fid, sizeof(fid), "%d", i);
896                                    path = gpath_fid2path(fid);
897                                    if (path == NULL)
898                                            die("GPATH is corrupted.");
899                                    fprintf(stderr, " deleting tags of %s\n", path + 2);
900                            }
901                    }
902            }
903          if (max_fid > 0)          if (max_fid > 0)
904                  gtags_delete_by_fidset(gtop, fidset, max_fid);                  gtags_delete_by_fidset(gtop, fidset, max_fid);
905    
# Line 1062  updatetags_optimized_for_speed(dbpath, r Line 908  updatetags_optimized_for_speed(dbpath, r
908                  gflags |= GTAGS_EXTRACTMETHOD;                  gflags |= GTAGS_EXTRACTMETHOD;
909          if (debug)          if (debug)
910                  gflags |= GTAGS_DEBUG;                  gflags |= GTAGS_DEBUG;
911          path = strbuf_value(extractlist);          path_list->sbuf = path_list->curp = strbuf_value(extractlist);
912          end = path + strbuf_getlen(extractlist);          end = path_list->curp + strbuf_getlen(extractlist);
913          while (path < end) {          while (path_list->curp < end) {
914                  gtags_add(gtop, comline, path, gflags);                  if (vflag)
915                            fprintf(stderr, " adding tags of %s\n", path_list->curp + 2);
916                    pathlen = strlen(path_list->curp);
917                    if (strbuf_getlen(path_list)
918                        && strbuf_getlen(path_list) + pathlen > path_list_max) {
919                            savec = *path_list->curp;
920                            gtags_add(gtop, comline, path_list, gflags);
921                            *path_list->curp = savec;
922                            path_list->sbuf = path_list->curp;
923                    }
924                  if (exitflag)                  if (exitflag)
925                          break;                          break;
926                  path += strlen(path) + 1;                  path_list->curp += pathlen + 1;
927          }          }
928            if (strbuf_getlen(path_list))
929                    gtags_add(gtop, comline, path_list, gflags);
930    
931          gtags_close(gtop);          gtags_close(gtop);
932          strbuf_close(sb);          strbuf_close(sb);
# Line 1089  createtags(dbpath, root, db) Line 946  createtags(dbpath, root, db)
946  {  {
947          const char *path;          const char *path;
948          GTOP *gtop;          GTOP *gtop;
949          int flags;          int flags, gflags;
950          const char *comline;          const char *comline;
951          STRBUF *sb = strbuf_open(0);          STRBUF *sb = strbuf_open(0);
952          int count = 0;          int count = 0;
953            STRBUF *path_list = strbuf_open(MAXPATHLEN);
954            int path_list_max;
955    
956          /*          /*
957           * get tag command.           * get tag command.
# Line 1105  createtags(dbpath, root, db) Line 964  createtags(dbpath, root, db)
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.");
967    
968            /*
969             * determine the maximum length of the list of paths.
970             */
971    #ifdef ARG_MAX
972            if (noxargs) {
973                    /* force processing files individually. */
974                    path_list_max = 0;
975            } else {
976                    path_list_max = ARG_MAX;
977                    path_list_max -= 2048;
978                    if (path_list_max > 20 * 1024)
979                            path_list_max = 20 * 1024;
980                    path_list_max -= env_size();
981                    path_list_max -= strbuf_getlen(sb);
982                    path_list_max -= 40;
983                    if (path_list_max < 0)
984                            path_list_max = 0;
985            }
986    #else
987            path_list_max = 0;
988    #endif
989    
990          flags = 0;          flags = 0;
991          /*          /*
992           * Compact format:           * Compact format:
# Line 1122  createtags(dbpath, root, db) Line 1004  createtags(dbpath, root, db)
1004          if (vflag > 1)          if (vflag > 1)
1005                  fprintf(stderr, " using tag command '%s <path>'.\n", comline);                  fprintf(stderr, " using tag command '%s <path>'.\n", comline);
1006          gtop = gtags_open(dbpath, root, db, GTAGS_CREATE, flags);          gtop = gtags_open(dbpath, root, db, GTAGS_CREATE, flags);
1007            if (gtop->format & GTAGS_COMPACT) {
1008                    /* force processing files individually. */
1009                    path_list_max = 0;
1010            }
1011            gflags = 0;
1012            if (extractmethod)
1013                    gflags |= GTAGS_EXTRACTMETHOD;
1014            if (debug)
1015                    gflags |= GTAGS_DEBUG;
1016          for (find_open(NULL); (path = find_read()) != NULL; ) {          for (find_open(NULL); (path = find_read()) != NULL; ) {
1017                  int     gflags = 0;                  int skip = 0;
                 int     skip = 0;  
1018    
1019                  /* a blank at the head of path means 'NOT SOURCE'. */                  /* a blank at the head of path means 'NOT SOURCE'. */
1020                  if (*path == ' ')                  if (*path == ' ')
# Line 1152  createtags(dbpath, root, db) Line 1042  createtags(dbpath, root, db)
1042                  }                  }
1043                  if (skip)                  if (skip)
1044                          continue;                          continue;
1045                  if (extractmethod)                  if (strbuf_getlen(path_list)
1046                          gflags |= GTAGS_EXTRACTMETHOD;                      && strbuf_getlen(path_list) + strlen(path) > path_list_max) {
1047                  if (debug)                          gtags_add(gtop, comline, path_list, gflags);
1048                          gflags |= GTAGS_DEBUG;                          strbuf_reset(path_list);
1049                  gtags_add(gtop, comline, path, gflags);                  }
1050                    strbuf_puts0(path_list, path);
1051          }          }
1052            if (strbuf_getlen(path_list))
1053                    gtags_add(gtop, comline, path_list, gflags);
1054          total = count;                          /* save total count */          total = count;                          /* save total count */
1055          find_close();          find_close();
1056          gtags_close(gtop);          gtags_close(gtop);
1057          strbuf_close(sb);          strbuf_close(sb);
1058            strbuf_close(path_list);
1059  }  }
1060  /*  /*
1061   * printconf: print configuration data.   * printconf: print configuration data.

Legend:
Removed from v.1.119  
changed lines
  Added in v.1.120

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26