/[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.77 by shigio, Sat Oct 8 14:59:00 2005 UTC revision 1.78 by shigio, Tue Oct 11 00:52:26 2005 UTC
# Line 40  Line 40 
40    
41  #include "char.h"  #include "char.h"
42  #include "conf.h"  #include "conf.h"
 #include "gparam.h"  
43  #include "dbop.h"  #include "dbop.h"
44  #include "die.h"  #include "die.h"
45    #include "gparam.h"
46  #include "gtagsop.h"  #include "gtagsop.h"
47  #include "locatestring.h"  #include "locatestring.h"
48  #include "makepath.h"  #include "makepath.h"
# Line 50  Line 50 
50  #include "gpathop.h"  #include "gpathop.h"
51  #include "split.h"  #include "split.h"
52  #include "strbuf.h"  #include "strbuf.h"
53    #include "strhash.h"
54  #include "strlimcpy.h"  #include "strlimcpy.h"
55  #include "strmake.h"  #include "strmake.h"
56    #include "varray.h"
57    
58  #define HASHBUCKETS     256  #define HASHBUCKETS     256
59    
 static unsigned int hashpjw(const char *);  
60  static int compare_lno(const void *, const void *);  static int compare_lno(const void *, const void *);
61  static void gtop_flush_htab(GTOP *);  static void flush_pool(GTOP *);
62  static const char *unpack_pathindex(const char *);  static const char *unpack_pathindex(const char *);
63  static const char *genrecord(GTOP *);  static const char *genrecord(GTOP *);
64  static regex_t reg;  static regex_t reg;
# Line 321  gtags_open(const char *dbpath, const cha Line 322  gtags_open(const char *dbpath, const cha
322                          gtop->ib = strbuf_open(MAXBUFLEN);                          gtop->ib = strbuf_open(MAXBUFLEN);
323                  else {                  else {
324                          gtop->sb = strbuf_open(0);                          gtop->sb = strbuf_open(0);
325                          gtop->htab = calloc(sizeof(struct gtop_compact_entry *), HASHBUCKETS);                          gtop->pool = strhash_open(HASHBUCKETS, NULL);
                         if (gtop->htab == NULL)  
                                 die("short of memory.");  
326                  }                  }
327          } else if (gtop->format == GTAGS_PATHINDEX && gtop->mode != GTAGS_READ)          } else if (gtop->format == GTAGS_PATHINDEX && gtop->mode != GTAGS_READ)
328                  gtop->sb = strbuf_open(0);                  gtop->sb = strbuf_open(0);
# Line 342  gtags_open(const char *dbpath, const cha Line 341  gtags_open(const char *dbpath, const cha
341  void  void
342  gtags_put(GTOP *gtop, const char *tag, const char *ctags_x)     /* virtually const */  gtags_put(GTOP *gtop, const char *tag, const char *ctags_x)     /* virtually const */
343  {  {
344          const char *tagname;          /*
345          SPLIT ptable;           * Standard format.
346          struct gtop_compact_entry *entry, **prev;           */
         int *lno;  
   
347          if (gtop->format == GTAGS_STANDARD) {          if (gtop->format == GTAGS_STANDARD) {
348                  /* entab(ctags_x); */                  /* entab(ctags_x); */
349                  dbop_put(gtop->dbop, tag, ctags_x);                  dbop_put(gtop->dbop, tag, ctags_x);
                 return;  
350          }          }
351          if (gtop->format == GTAGS_PATHINDEX) {          /*
352             * Only pathindex format. (not compact format)
353             */
354            else if (gtop->format == GTAGS_PATHINDEX) {
355                  char *p = locatestring(ctags_x, "./", MATCH_FIRST);                  char *p = locatestring(ctags_x, "./", MATCH_FIRST);
356                  const char *fid, *path;                  const char *fid, *path;
357                  int savec;                  int savec;
# Line 374  gtags_put(GTOP *gtop, const char *tag, c Line 373  gtags_put(GTOP *gtop, const char *tag, c
373                  strbuf_puts(gtop->sb, fid);                  strbuf_puts(gtop->sb, fid);
374                  strbuf_puts(gtop->sb, p);                  strbuf_puts(gtop->sb, p);
375                  dbop_put(gtop->dbop, tag, strbuf_value(gtop->sb));                  dbop_put(gtop->dbop, tag, strbuf_value(gtop->sb));
                 return;  
376          }          }
377          /*          /*
378           * gtop->format & GTAGS_COMPACT           * Compact format. (gtop->format & GTAGS_COMPACT)
379           */           */
380          if (split((char *)ctags_x, 4, &ptable) != 4) {          else {
381                  recover(&ptable);                  SPLIT ptable;
382                  die("illegal tag format.\n'%s'", ctags_x);                  struct sh_entry *entry;
383          }                  VARRAY *vb;
384          tagname = ptable.part[PART_TAG].start;                  int *lno;
         /*  
          * Register each record into the hash table.  
          * Duplicated records will be combined.  
          */  
         if (gtop->prev_path[0] && strcmp(gtop->prev_path, ptable.part[PART_PATH].start))  
                 gtop_flush_htab(gtop);  
         strlimcpy(gtop->prev_path, ptable.part[PART_PATH].start, sizeof(gtop->prev_path));  
         for (prev = gtop->htab + hashpjw(tagname) % HASHBUCKETS;  
              (entry = *prev) != NULL;  
              prev = &entry->next) {  
                 if (strcmp(entry->tag, tagname) == 0)  
                         break;  
         }  
         if (entry == NULL) {  
                 entry = malloc(offsetof(struct gtop_compact_entry, tag) + strlen(tagname) + 1);  
                 if (entry == NULL)  
                         die("short of memory.");  
                 entry->next = NULL;  
                 entry->vb = varray_open(sizeof(int), 100);  
                 strcpy(entry->tag, tagname);  
                 *prev = entry;  
         }  
         lno = varray_append(entry->vb);  
         *lno = atoi(ptable.part[PART_LNO].start);  
         recover(&ptable);  
 }  
 /*  
  * hashpjw: calculate hash value for given string.  
  *  
  *      i)      string  
  *      r)      hash value  
  */  
 static unsigned int  
 hashpjw(const char *s)  
 {  
         unsigned int h, g;  
385    
386          h = strlen(s);                  if (split((char *)ctags_x, 4, &ptable) != 4) {
387          while (*s != '\0') {                          recover(&ptable);
388                  h <<= 4;                          die("illegal tag format.\n'%s'", ctags_x);
389                  h += (unsigned char)*s++;                  }
390                  g = h & 0xf0000000;                  /*
391                  if (g != 0)                   * Flush the pool when path is changed.
392                          h = h ^ (g >> 24) ^ g;                   * Line numbers in the pool will be sorted and duplicated
393                     * records will be combined.
394                     *
395                     * pool    "funcA"   | 1| 3| 7|23|11| 2|...
396                     *           v
397                     * output  funcA 33 1,2,3,7,11,23...
398                     */
399                    if (gtop->prev_path[0] && strcmp(gtop->prev_path, ptable.part[PART_PATH].start)) {
400                            flush_pool(gtop);
401                            strhash_reset(gtop->pool);
402                    }
403                    strlimcpy(gtop->prev_path, ptable.part[PART_PATH].start, sizeof(gtop->prev_path));
404                    /*
405                     * Register each record into the pool.
406                     *
407                     * Pool image:
408                     *
409                     * tagname   lno
410                     * ------------------------------
411                     * "funcA"   | 1| 3| 7|23|11| 2|...
412                     * "funcB"   |34| 2| 5|66| 3|...
413                     * ...
414                     */
415                    entry = strhash_assign(gtop->pool, ptable.part[PART_TAG].start, 1);
416                    if (entry->value == NULL)
417                            entry->value = vb = varray_open(sizeof(int), 100);
418                    else
419                            vb = (VARRAY *)entry->value;
420                    lno = varray_append(vb);
421                    *lno = atoi(ptable.part[PART_LNO].start);
422                    recover(&ptable);
423          }          }
   
         return h;  
424  }  }
425  /*  /*
426   * compare_lno: compare function for sorting line number.   * compare_lno: compare function for sorting line number.
# Line 441  compare_lno(const void *s1, const void * Line 431  compare_lno(const void *s1, const void *
431          return *(const int *)s1 - *(const int *)s2;          return *(const int *)s1 - *(const int *)s2;
432  }  }
433  /*  /*
434   * gtop_flush_htab: register each record into the tag database and delete from the hash table.   * flush_pool: flush the pool and write is as compact format.
435   *   *
436   *      i)      gtop    descripter of GTOP   *      i)      gtop    descripter of GTOP
437   */   */
438  static void  static void
439  gtop_flush_htab(GTOP *gtop)  flush_pool(GTOP *gtop)
440  {  {
441          const char *path, *key;          struct sh_entry *entry;
442          struct gtop_compact_entry *entry, *next;          const char *path = gtop->prev_path;
         int *lno_array;  
         int i, j, savelen;  
443    
         path = gtop->prev_path;  
444          if (gtop->format & GTAGS_PATHINDEX) {          if (gtop->format & GTAGS_PATHINDEX) {
445                  path = gpath_path2fid(gtop->prev_path);                  path = gpath_path2fid(gtop->prev_path);
446                  if (path == NULL)                  if (path == NULL)
447                          die("GPATH is corrupted.('%s' not found)", gtop->prev_path);                          die("GPATH is corrupted.('%s' not found)", gtop->prev_path);
448          }          }
449            /*
450             * Write records as compact format and free line number table
451             * for each entry in the pool.
452             */
453            for (entry = strhash_first(gtop->pool); entry; entry = strhash_next(gtop->pool)) {
454                    VARRAY *vb = (VARRAY *)entry->value;
455                    int *lno_array = varray_assign(vb, 0, 0);
456                    const char *key = entry->name;
457    
458          for (i = 0; i < HASHBUCKETS; i++) {                  /*
459                  for (entry = gtop->htab[i]; entry != NULL; entry = next) {                   * extract method when class method definition.
460                          /*                   *
461                           * extract method when class method definition.                   * Ex: Class::method(...)
462                           *                   *
463                           * Ex: Class::method(...)                   * key  = 'method'
464                           *                   * data = 'Class::method  103 ./class.cpp ...'
465                           * key  = 'method'                   */
466                           * data = 'Class::method  103 ./class.cpp ...'                  if (gtop->flags & GTAGS_EXTRACTMETHOD) {
467                           */                          if ((key = locatestring(entry->name, ".", MATCH_LAST)) != NULL)
468                          key = entry->tag;                                  key++;
469                          if (gtop->flags & GTAGS_EXTRACTMETHOD) {                          else if ((key = locatestring(entry->name, "::", MATCH_LAST)) != NULL)
470                                  if ((key = locatestring(entry->tag, ".", MATCH_LAST)) != NULL)                                  key += 2;
471                                          key++;                          else
472                                  else if ((key = locatestring(entry->tag, "::", MATCH_LAST)) != NULL)                                  key = entry->name;
473                                          key += 2;                  }
474                                  else                  /* Sort line number table */
475                                          key = entry->tag;                  qsort(lno_array, vb->length, sizeof(int), compare_lno);
476                          }  
477                          lno_array = varray_assign(entry->vb, 0, 0);                  strbuf_reset(gtop->sb);
478                          qsort(lno_array, entry->vb->length, sizeof(int), compare_lno);                  strbuf_puts(gtop->sb, entry->name);
479                          strbuf_reset(gtop->sb);                  strbuf_putc(gtop->sb, ' ');
480                          strbuf_puts(gtop->sb, entry->tag);                  strbuf_puts(gtop->sb, path);
481                          strbuf_putc(gtop->sb, ' ');                  strbuf_putc(gtop->sb, ' ');
482                          strbuf_puts(gtop->sb, path);                  {
483                          strbuf_putc(gtop->sb, ' ');                          int savelen = strbuf_getlen(gtop->sb);
484                          savelen = strbuf_getlen(gtop->sb);                          int last = 0;           /* line 0 doesn't exist */
485                          for (j = 0; j < entry->vb->length; j++) {                          int i;
486                                  if ((gtop->flags & GTAGS_UNIQUE) && j > 0  
487                                      && lno_array[j - 1] == lno_array[j])                          for (i = 0; i < vb->length; i++) {
488                                    int n = lno_array[i];
489    
490                                    if ((gtop->flags & GTAGS_UNIQUE) && n == last)
491                                          continue;                                          continue;
492                                  if (strbuf_getlen(gtop->sb) > savelen)                                  if (strbuf_getlen(gtop->sb) > savelen)
493                                          strbuf_putc(gtop->sb, ',');                                          strbuf_putc(gtop->sb, ',');
494                                  strbuf_putn(gtop->sb, lno_array[j]);                                  strbuf_putn(gtop->sb, n);
495                                  if (strbuf_getlen(gtop->sb) > DBOP_PAGESIZE / 4) {                                  if (strbuf_getlen(gtop->sb) > DBOP_PAGESIZE / 4) {
496                                          dbop_put(gtop->dbop, key, strbuf_value(gtop->sb));                                          dbop_put(gtop->dbop, key, strbuf_value(gtop->sb));
497                                          strbuf_setlen(gtop->sb, savelen);                                          strbuf_setlen(gtop->sb, savelen);
498                                  }                                  }
499                                    last = n;
500                          }                          }
501                          if (strbuf_getlen(gtop->sb) > savelen)                          if (strbuf_getlen(gtop->sb) > savelen)
502                                  dbop_put(gtop->dbop, key, strbuf_value(gtop->sb));                                  dbop_put(gtop->dbop, key, strbuf_value(gtop->sb));
                         varray_close(entry->vb);  
                         next = entry->next;  
                         free(entry);  
503                  }                  }
504                  gtop->htab[i] = NULL;                  /* Free line number table */
505                    varray_close(vb);
506          }          }
507  }  }
508  /*  /*
# Line 754  gtags_next(GTOP *gtop) Line 751  gtags_next(GTOP *gtop)
751  void  void
752  gtags_close(GTOP *gtop)  gtags_close(GTOP *gtop)
753  {  {
754          if (gtop->htab) {          if (gtop->pool) {
755                  if (gtop->prev_path[0])                  if (gtop->prev_path[0])
756                          gtop_flush_htab(gtop);                          flush_pool(gtop);
757                  free(gtop->htab);                  strhash_close(gtop->pool);
758          }          }
759          if (gtop->sb)          if (gtop->sb)
760                  strbuf_close(gtop->sb);                  strbuf_close(gtop->sb);

Legend:
Removed from v.1.77  
changed lines
  Added in v.1.78

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