/[global]/global/libutil/gtagsop.c
ViewVC logotype

Diff of /global/libutil/gtagsop.c

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

revision 1.79 by shigio, Tue Oct 11 01:37:59 2005 UTC revision 1.80 by shigio, Mon Oct 17 04:51:04 2005 UTC
# Line 103  static regex_t reg; Line 103  static regex_t reg;
103   *   *
104   * Since we know the format version 3 is better than 1 in all aspect,   * Since we know the format version 3 is better than 1 in all aspect,
105   * the default format version will be changed into 3 in the future.   * the default format version will be changed into 3 in the future.
106     *
107     * [Example of each format]
108     *
109     *    [gtags/gtags.c]
110     *    +-----------------------------
111     *   1|...
112     *   2| * Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005
113     *  .....
114     * 203|main(int argc, char **argv)
115     *    |{
116     *
117     * (Standard format)
118     *
119     * 0                 1   2                3
120     * ------------------------------------------------------------------
121     * main              203 ./gtags/gtags.c  main(int argc, char **argv)
122     *
123     * (Pathindex format)
124     * 0                 1   2   3
125     * ----------------------------------------------------
126     * main              203 22  main(int argc, char **argv)
127     *
128     * (Compact format)
129     *
130     * 0    1  2
131     * ----------------------------------------------------
132     * main 22 203
133   */   */
134  static int support_version = 3; /* acceptable format version   */  static int support_version = 3; /* acceptable format version   */
135  static const char *tagslist[] = {"GPATH", "GTAGS", "GRTAGS", "GSYMS"};  static const char *tagslist[] = {"GPATH", "GTAGS", "GRTAGS", "GSYMS"};
# Line 158  makecommand(const char *comline, STRBUF Line 185  makecommand(const char *comline, STRBUF
185  /*  /*
186   * formatcheck: check format of tag command's output   * formatcheck: check format of tag command's output
187   *   *
188   *      i)      line    input   *      i)      ctags_x tag line (ctags -x format)
189   *   *
190   * 0                 1  2              3   * 0                 1  2              3
191   * ----------------------------------------------------   * ----------------------------------------------------
# Line 167  makecommand(const char *comline, STRBUF Line 194  makecommand(const char *comline, STRBUF
194  void  void
195  formatcheck(const char *ctags_x)                /* virtually const */  formatcheck(const char *ctags_x)                /* virtually const */
196  {  {
         int n;  
197          const char *p;          const char *p;
198          SPLIT ptable;          SPLIT ptable;
199    
200          /*          /*
201           * Extract parts.           * Extract parts.
202           */           */
203          n = split((char *)ctags_x, 4, &ptable);          split((char *)ctags_x, 4, &ptable);
204    
205          /*          /*
206           * line number           * line number
207           */           */
208          if (n < 4) {          if (ptable.npart < 4) {
209                  recover(&ptable);                  recover(&ptable);
210                  die("too small number of parts.\n'%s'", ctags_x);                  die("too small number of parts.\n'%s'", ctags_x);
211          }          }
# Line 596  gtags_add(GTOP *gtop, const char *comlin Line 622  gtags_add(GTOP *gtop, const char *comlin
622  void  void
623  gtags_delete(GTOP *gtop, IDSET *deleteset)  gtags_delete(GTOP *gtop, IDSET *deleteset)
624  {  {
625          const char *line, *p;          const char *tagline, *s_fid;
626          SPLIT ptable;          SPLIT ptable;
627          int fid, n;          int fid;
628    
629          for (line = dbop_first(gtop->dbop, NULL, NULL, 0); line; line = dbop_next(gtop->dbop)) {          for (tagline = dbop_first(gtop->dbop, NULL, NULL, 0); tagline; tagline = dbop_next(gtop->dbop)) {
630                  /*                  /*
631                   * Extract the path, and if needed, convert it into the file id.                   * Extract fid from the tag line.
632                   */                   */
633                  n = split((char *)line, 4, &ptable);                  split((char *)tagline, 4, &ptable);
634                  if (gtop->format & GTAGS_COMPACT) {                  if (gtop->format == GTAGS_STANDARD) {
635                          if (n != 3)                          if (ptable.npart < 4) {
                                 die("illegal compact format.\n");  
                         p = ptable.part[1].start;  
                 } else {  
                         if (n < 4) {  
636                                  recover(&ptable);                                  recover(&ptable);
637                                  die("too small number of parts.\n'%s'", line);                                  die("too small number of parts.\n'%s'", tagline);
638                          }                          }
639                          p = ptable.part[2].start;                          s_fid = gpath_path2fid(ptable.part[PART_PATH].start);
640                  }                          if (s_fid == NULL)
                 if (!(gtop->format & GTAGS_PATHINDEX)) {  
                         p = gpath_path2fid(p);  
                         if (p == NULL)  
641                                  die("GPATH is corrupted.");                                  die("GPATH is corrupted.");
642                  }                  }
643                  fid = atoi(p);                  else if (gtop->format == GTAGS_PATHINDEX) {
644                            if (ptable.npart < 4) {
645                                    recover(&ptable);
646                                    die("too small number of parts in pathindex format.\n'%s'", tagline);
647                            }
648                            s_fid = ptable.part[PART_FID_PIDX].start;
649                    } else {        /* gtop->format & GTAGS_COMPACT */
650                            if (ptable.npart != 3) {
651                                    recover(&ptable);
652                                    die("too small number of parts in compact format.\n'%s'", tagline);
653                            }
654                            s_fid = ptable.part[PART_FID_COMP].start;
655                    }
656                    fid = atoi(s_fid);
657                  recover(&ptable);                  recover(&ptable);
658                  /*                  /*
659                   * If the file id exists in the deleteset, delete the record.                   * If the file id exists in the deleteset, delete the tagline.
660                   */                   */
661                  if (idset_contains(deleteset, fid))                  if (idset_contains(deleteset, fid))
662                          dbop_delete(gtop->dbop, NULL);                          dbop_delete(gtop->dbop, NULL);
# Line 651  gtags_first(GTOP *gtop, const char *patt Line 683  gtags_first(GTOP *gtop, const char *patt
683          int dbflags = 0;          int dbflags = 0;
684          char prefix[IDENTLEN+1];          char prefix[IDENTLEN+1];
685          regex_t *preg = &reg;          regex_t *preg = &reg;
686          const char *key, *p, *line;          const char *key, *tagline;
687          int regflags = 0;          int regflags = 0;
688    
689          gtop->flags = flags;          gtop->flags = flags;
# Line 665  gtags_first(GTOP *gtop, const char *patt Line 697  gtags_first(GTOP *gtop, const char *patt
697          if (flags & GTOP_IGNORECASE)          if (flags & GTOP_IGNORECASE)
698                  regflags |= REG_ICASE;                  regflags |= REG_ICASE;
699    
700            /*
701             * Get key and compiled regular expression for dbop_xxxx().
702             */
703          if (flags & GTOP_NOREGEX) {          if (flags & GTOP_NOREGEX) {
704                  key = pattern;                  key = pattern;
705                  preg = NULL;                  preg = NULL;
706          } else if (pattern == NULL || !strcmp(pattern, ".*")) {          } else if (pattern == NULL || !strcmp(pattern, ".*")) {
707                    /*
708                     * Since the regular expression '.*' matches to any record,
709                     * we take sequential read method.
710                     */
711                  key = NULL;                  key = NULL;
712                  preg = NULL;                  preg = NULL;
713          } else if (isregex(pattern) && regcomp(preg, pattern, regflags) == 0) {          } else if (isregex(pattern) && regcomp(preg, pattern, regflags) == 0) {
714                    const char *p;
715    
716                    /*
717                     * If the pattern include '^' + some non regular expression
718                     * characters like '^aaa[0-9]', we take prefix read method
719                     * with the non regular expression part as the prefix.
720                     */
721                  if (!(flags & GTOP_IGNORECASE) && *pattern == '^' && *(p = pattern + 1) && !isregexchar(*p)) {                  if (!(flags & GTOP_IGNORECASE) && *pattern == '^' && *(p = pattern + 1) && !isregexchar(*p)) {
722                          int i = 0;                          int i = 0;
723    
# Line 687  gtags_first(GTOP *gtop, const char *patt Line 733  gtags_first(GTOP *gtop, const char *patt
733                  key = pattern;                  key = pattern;
734                  preg = NULL;                  preg = NULL;
735          }          }
736          if ((line = dbop_first(gtop->dbop, key, preg, dbflags)) == NULL)          tagline = dbop_first(gtop->dbop, key, preg, dbflags);
737                  return NULL;          if (tagline) {
738          if (gtop->format == GTAGS_STANDARD || gtop->flags & GTOP_KEY)                  if (gtop->format == GTAGS_STANDARD || gtop->flags & GTOP_KEY)
739                  return line;                          return tagline;
740          if (gtop->format == GTAGS_PATHINDEX)                  else if (gtop->format == GTAGS_PATHINDEX)
741                  return unpack_pathindex(line);                          return unpack_pathindex(tagline);
742          /*                  else {  /* Compact format */
743           * Compact format.                          gtop->line = (char *)tagline;
744           */                          gtop->opened = 0;
745          gtop->line = (char *)line;              /* gtop->line = $0 */                          return genrecord(gtop);
746          gtop->opened = 0;                  }
747          return genrecord(gtop);          }
748            return NULL;
749  }  }
750  /*  /*
751   * gtags_next: return followed record   * gtags_next: return followed record
# Line 710  gtags_first(GTOP *gtop, const char *patt Line 757  gtags_first(GTOP *gtop, const char *patt
757  const char *  const char *
758  gtags_next(GTOP *gtop)  gtags_next(GTOP *gtop)
759  {  {
760          const char *line;          const char *tagline;
761          /*          /*
762           * If it is standard format or only key.           * If it is standard format or only key.
763           * Just return it.           * Just return it.
764           */           */
765          if (gtop->format == GTAGS_STANDARD || gtop->flags & GTOP_KEY)          if (gtop->format == GTAGS_STANDARD || gtop->flags & GTOP_KEY) {
766                  return dbop_next(gtop->dbop);                  return dbop_next(gtop->dbop);
767            }
768          /*          /*
769           * Pathindex format.           * Pathindex format.
770           */           */
771          if (gtop->format == GTAGS_PATHINDEX) {          else if (gtop->format == GTAGS_PATHINDEX) {
772                  line = dbop_next(gtop->dbop);                  tagline = dbop_next(gtop->dbop);
773                  if (line == NULL)                  return (tagline == NULL) ? NULL : unpack_pathindex(tagline);
                         return NULL;  
                 return unpack_pathindex(line);  
774          }          }
775          /*          /*
776           * gtop->format & GTAGS_COMPACT           * gtop->format & GTAGS_COMPACT
777           */           */
778          if ((line = genrecord(gtop)) != NULL)          else {
779                  return line;                  const char *ctags_x;
780          /*  
781           * read next record.                  /*
782           */                   * If some unpacked record exists then return one of them
783          if ((line = dbop_next(gtop->dbop)) == NULL)                   * else read the next tag line.
784                  return line;                   */
785          gtop->line = (char *)line;              /* gtop->line = $0 */                  if ((ctags_x = genrecord(gtop)) != NULL)
786          gtop->opened = 0;                          return ctags_x;
787          return genrecord(gtop);                  if ((tagline = dbop_next(gtop->dbop)) == NULL)
788                            return NULL;
789                    gtop->line = (char *)tagline;           /* gtop->line = $0 */
790                    gtop->opened = 0;
791                    return genrecord(gtop);
792            }
793  }  }
794  /*  /*
795   * gtags_close: close tag file   * gtags_close: close tag file
# Line 765  gtags_close(GTOP *gtop) Line 816  gtags_close(GTOP *gtop)
816  /*  /*
817   * unpack_pathindex: convert pathindex format into standard format.   * unpack_pathindex: convert pathindex format into standard format.
818   *   *
819   *      i)      line    tag line   *      i)      tagline tag line (pathindex format)
820   */   */
821  static const char *  static const char *
822  unpack_pathindex(const char *line)      /* virtually const */  unpack_pathindex(const char *tagline)   /* virtually const */
823  {  {
824          STATIC_STRBUF(output);          STATIC_STRBUF(output);
825          SPLIT ptable;          SPLIT ptable;
         int n;  
826          const char *path;          const char *path;
827    
828          n = split((char *)line, 4, &ptable);          split((char *)tagline, 4, &ptable);
829          if (n < 4) {          if (ptable.npart < 4) {
830                  recover(&ptable);                  recover(&ptable);
831                  die("illegal tag format.'%s'\n", line);                  die("illegal tag format.'%s'\n", tagline);
832          }          }
833          /*          /*
834           * extract path and convert into file number.           * extract file id and convert into path name.
835           */           */
836          path = gpath_fid2path(ptable.part[2].start);          path = gpath_fid2path(ptable.part[PART_FID_PIDX].start);
837          if (path == NULL)          if (path == NULL)
838                  die("GPATH is corrupted.(fid '%s' not found)", ptable.part[2].start);                  die("GPATH is corrupted.(fid '%s' not found)", ptable.part[PART_FID_PIDX].start);
839          recover(&ptable);          recover(&ptable);
840          /*          /*
841           * copy line with converting.           * copy line with converting fid into path name.
842           */           */
843          strbuf_clear(output);          strbuf_clear(output);
844          strbuf_nputs(output, line, ptable.part[2].start - line);          strbuf_nputs(output, tagline, ptable.part[PART_FID_PIDX].start - tagline);
845          strbuf_puts(output, path);          strbuf_puts(output, path);
846          strbuf_puts(output, ptable.part[2].end);          strbuf_puts(output, ptable.part[PART_FID_PIDX].end);
847    
848          return strbuf_value(output);          return strbuf_value(output);
849  }  }
# Line 806  unpack_pathindex(const char *line)     /* vi Line 856  unpack_pathindex(const char *line)     /* vi
856  static const char *  static const char *
857  genrecord(GTOP *gtop)  genrecord(GTOP *gtop)
858  {  {
         SPLIT ptable;  
         static char output[MAXBUFLEN+1];  
         char path[MAXPATHLEN+1];  
         static char buf[1];  
         const char *buffer = buf;  
859          const char *lnop;          const char *lnop;
         int tagline;  
860    
861          if (!gtop->opened) {          if (!gtop->opened) {
862                  int n;                  SPLIT ptable;
863                  const char *p;                  const char *fid, *path;
864    
865                  gtop->opened = 1;                  gtop->opened = 1;
866                  n = split(gtop->line, 3, &ptable);                  split(gtop->line, 3, &ptable);
867                  if (n != 3) {                  if (ptable.npart != 3) {
868                          recover(&ptable);                          recover(&ptable);
869                          die("illegal compact format. '%s'\n", gtop->line);                          die("illegal compact format. '%s'\n", gtop->line);
870                  }                  }
871                  /*                  /* Tag name */
872                   * gtop->tag = part[0]                  strlimcpy(gtop->tag, ptable.part[PART_TAG].start, sizeof(gtop->tag));
                  */  
                 strlimcpy(gtop->tag, ptable.part[0].start, sizeof(gtop->tag));  
873    
874                  /*                  /* Path name */
875                   * gtop->path = part[1]                  fid = ptable.part[PART_FID_COMP].start;
876                   */                  if ((path = gpath_fid2path(fid)) == NULL)
877                  p = ptable.part[1].start;                          die("GPATH is corrupted.('%s' not found)", fid);
878                  if (gtop->format & GTAGS_PATHINDEX) {                  strlimcpy(gtop->path, path, sizeof(gtop->path));
                         const char *q;  
                         if ((q = gpath_fid2path(p)) == NULL)  
                                 die("GPATH is corrupted.('%s' not found)", p);  
                         p = q;  
                 }  
                 strlimcpy(gtop->path, p, sizeof(gtop->path));  
879    
880                    /* line number list */
881                    gtop->lnop = ptable.part[PART_LNO_COMP].start;
882                  /*                  /*
883                   * gtop->lnop = part[2]                   * Open source file.
884                   */                   */
                 gtop->lnop = ptable.part[2].start;  
   
                 if (gtop->root)  
                         snprintf(path, sizeof(path),  
                                 "%s/%s", gtop->root, &gtop->path[2]);  
                 else  
                         snprintf(path, sizeof(path), "%s", &gtop->path[2]);  
885                  if (!(gtop->flags & GTOP_NOSOURCE)) {                  if (!(gtop->flags & GTOP_NOSOURCE)) {
886                          if ((gtop->fp = fopen(path, "r")) != NULL)                          char path[MAXPATHLEN+1];
887                                  gtop->lno = 0;  
888                            if (gtop->root)
889                                    snprintf(path, sizeof(path),
890                                            "%s/%s", gtop->root, &gtop->path[2]);
891                            else
892                                    snprintf(path, sizeof(path), "%s", &gtop->path[2]);
893                            gtop->fp = fopen(path, "r");
894                            gtop->lno = 0;
895                  }                  }
896                  recover(&ptable);                  recover(&ptable);
897          }          }
898    
899          lnop = gtop->lnop;          lnop = gtop->lnop;
900          if (*lnop >= '0' && *lnop <= '9') {          if (*lnop >= '0' && *lnop <= '9') {
901                    const char *src = "";
902                    static char output[MAXBUFLEN+1];
903                    int lno;
904    
905                  /* get line number */                  /* get line number */
906                  for (tagline = 0; *lnop >= '0' && *lnop <= '9'; lnop++)                  for (lno = 0; *lnop >= '0' && *lnop <= '9'; lnop++)
907                          tagline = tagline * 10 + *lnop - '0';                          lno = lno * 10 + *lnop - '0';
908                  if (*lnop == ',')                  if (*lnop == ',')
909                          lnop++;                          lnop++;
910                  gtop->lnop = lnop;                  gtop->lnop = lnop;
911                  if (gtop->fp) {                  if (gtop->fp) {
912                          if (gtop->lno == tagline)                          /*
913                             * If it is duplicate line, return the previous line.
914                             */
915                            if (gtop->lno == lno)
916                                  return output;                                  return output;
917                          while (gtop->lno < tagline) {                          while (gtop->lno < lno) {
918                                  if (!(buffer = strbuf_fgets(gtop->ib, gtop->fp, STRBUF_NOCRLF)))                                  if (!(src = strbuf_fgets(gtop->ib, gtop->fp, STRBUF_NOCRLF)))
919                                          die("unexpected end of file. '%s'", gtop->path);                                          die("unexpected end of file. '%s'", gtop->path);
920                                  strbuf_trim(gtop->ib);                                  strbuf_trim(gtop->ib);
921                                  gtop->lno++;                                  gtop->lno++;
922                          }                          }
923                  }                  }
924                  snprintf(output, sizeof(output), "%-16s %4d %-16s %s",                  snprintf(output, sizeof(output), "%-16s %4d %-16s %s",
925                          gtop->tag, tagline, gtop->path, buffer);                          gtop->tag, lno, gtop->path, src);
926                  return output;                  return output;
927            } else {
928                    if (gtop->opened && gtop->fp != NULL) {
929                            gtop->opened = 0;
930                            fclose(gtop->fp);
931                            gtop->fp = NULL;
932                    }
933                    return NULL;
934          }          }
         if (gtop->opened && gtop->fp != NULL) {  
                 gtop->opened = 0;  
                 fclose(gtop->fp);  
                 gtop->fp = NULL;  
         }  
         return NULL;  
935  }  }

Legend:
Removed from v.1.79  
changed lines
  Added in v.1.80

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