/[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.70 by h-iwamoto, Wed Jul 6 12:01:16 2005 UTC revision 1.71 by h-iwamoto, Fri Jul 22 13:08:20 2005 UTC
# Line 27  Line 27 
27  #include <stdio.h>  #include <stdio.h>
28  #ifdef STDC_HEADERS  #ifdef STDC_HEADERS
29  #include <stdlib.h>  #include <stdlib.h>
30    #include <stddef.h>
31  #endif  #endif
32  #ifdef HAVE_STRING_H  #ifdef HAVE_STRING_H
33  #include <string.h>  #include <string.h>
# Line 53  Line 54 
54  #include "strmake.h"  #include "strmake.h"
55  #include "tab.h"  #include "tab.h"
56    
57    #define HASHBUCKETS     256
58    
59    static unsigned int hashpjw(const char *);
60    static int compare_lno(const void *, const void *);
61    static void gtop_flush_htab(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 324  gtags_open(dbpath, root, db, mode, flags Line 330  gtags_open(dbpath, root, db, mode, flags
330                  strlimcpy(gtop->root, root, sizeof(gtop->root));                  strlimcpy(gtop->root, root, sizeof(gtop->root));
331                  if (gtop->mode == GTAGS_READ)                  if (gtop->mode == GTAGS_READ)
332                          gtop->ib = strbuf_open(MAXBUFLEN);                          gtop->ib = strbuf_open(MAXBUFLEN);
333                  else                  else {
334                          gtop->sb = strbuf_open(0);                          gtop->sb = strbuf_open(0);
335                            gtop->htab = calloc(sizeof(struct gtop_compact_entry *), HASHBUCKETS);
336                            if (gtop->htab == NULL)
337                                    die("short of memory.");
338                    }
339          } else if (gtop->format == GTAGS_PATHINDEX && gtop->mode != GTAGS_READ)          } else if (gtop->format == GTAGS_PATHINDEX && gtop->mode != GTAGS_READ)
340                  gtop->sb = strbuf_open(0);                  gtop->sb = strbuf_open(0);
341          return gtop;          return gtop;
# Line 346  gtags_put(gtop, tag, record) Line 356  gtags_put(gtop, tag, record)
356          const char *tag;          const char *tag;
357          const char *record;             /* virtually const */          const char *record;             /* virtually const */
358  {  {
359          const char *line, *path, *fid;          const char *line, *path;
360          SPLIT ptable;          SPLIT ptable;
361            struct gtop_compact_entry *entry, **prev;
362            int *lno;
363    
364          if (gtop->format == GTAGS_STANDARD) {          if (gtop->format == GTAGS_STANDARD) {
365                  /* entab(record); */                  /* entab(record); */
# Line 356  gtags_put(gtop, tag, record) Line 368  gtags_put(gtop, tag, record)
368          }          }
369          if (gtop->format == GTAGS_PATHINDEX) {          if (gtop->format == GTAGS_PATHINDEX) {
370                  char *p = locatestring(record, "./", MATCH_FIRST);                  char *p = locatestring(record, "./", MATCH_FIRST);
371                    const char *fid;
372                  int savec;                  int savec;
373    
374                  if (p == NULL)                  if (p == NULL)
# Line 387  gtags_put(gtop, tag, record) Line 400  gtags_put(gtop, tag, record)
400          line = ptable.part[1].start;          line = ptable.part[1].start;
401          path = ptable.part[2].start;          path = ptable.part[2].start;
402          /*          /*
403           * First time, it occurs, because 'prev_tag' and 'prev_path' are NULL.           * Register each record into the hash table.
404             * Duplicated records will be combined.
405           */           */
406          if (strcmp(gtop->prev_tag, tag) || strcmp(gtop->prev_path, path)) {          if (gtop->prev_path[0] && strcmp(gtop->prev_path, path))
407                  if (gtop->prev_tag[0]) {                  gtop_flush_htab(gtop);
408                          dbop_put(gtop->dbop, gtop->prev_tag, strbuf_value(gtop->sb));          strlimcpy(gtop->prev_path, path, sizeof(gtop->prev_path));
409                  }          for (prev = gtop->htab + hashpjw(record) % HASHBUCKETS;
410                  strlimcpy(gtop->prev_tag, tag, sizeof(gtop->prev_tag));               (entry = *prev) != NULL;
411                  strlimcpy(gtop->prev_path, path, sizeof(gtop->prev_path));               prev = &entry->next) {
412                  /*                  if (strcmp(entry->tag, record) == 0)
413                   * Start creating new record.                          break;
414                   */          }
415                  strbuf_reset(gtop->sb);          if (entry == NULL) {
416                  strbuf_puts(gtop->sb, strmake(record, " \t"));                  entry = malloc(offsetof(struct gtop_compact_entry, tag) + strlen(record) + 1);
417                  strbuf_putc(gtop->sb, ' ');                  if (entry == NULL)
418                  if (gtop->format & GTAGS_PATHINDEX) {                          die("short of memory.");
419                          fid = gpath_path2fid(path);                  entry->next = NULL;
420                          if (fid == NULL)                  entry->vb = varray_open(sizeof(int), 100);
421                                  die("GPATH is corrupted.('%s' not found)", path);                  strcpy(entry->tag, record);
422                          path = fid;                  *prev = entry;
                 }  
                 strbuf_puts(gtop->sb, path);  
                 strbuf_putc(gtop->sb, ' ');  
                 strbuf_puts(gtop->sb, line);  
         } else {  
                 strbuf_putc(gtop->sb, ',');  
                 strbuf_puts(gtop->sb, line);  
                 if (strbuf_getlen(gtop->sb) > DBOP_PAGESIZE / 4)  
                         gtop->prev_path[0] = '\0';  
423          }          }
424            lno = varray_append(entry->vb);
425            *lno = atoi(line);
426          recover(&ptable);          recover(&ptable);
427  }  }
428  /*  /*
429     * hashpjw: calculate hash value for given string.
430     *
431     *      i)      string
432     *      r)      hash value
433     */
434    static unsigned int
435    hashpjw(s)
436            const char *s;
437    {
438            unsigned int h, g;
439    
440            h = strlen(s);
441            while (*s != '\0') {
442                    h <<= 4;
443                    h += (unsigned char)*s++;
444                    g = h & 0xf0000000;
445                    if (g != 0)
446                            h = h ^ (g >> 24) ^ g;
447            }
448    
449            return h;
450    }
451    /*
452     * compare_lno: compare function for sorting line number.
453     */
454    static int
455    compare_lno(s1, s2)
456            const void *s1;
457            const void *s2;
458    {
459            return *(const int *)s1 - *(const int *)s2;
460    }
461    /*
462     * gtop_flush_htab: register each record into the tag database and delete from the hash table.
463     *
464     *      i)      gtop    descripter of GTOP
465     */
466    static void
467    gtop_flush_htab(gtop)
468            GTOP *gtop;
469    {
470            const char *path, *key;
471            struct gtop_compact_entry *entry, *next;
472            int *lno_array;
473            int i, j, savelen;
474    
475            path = gtop->prev_path;
476            if (gtop->format & GTAGS_PATHINDEX) {
477                    path = gpath_path2fid(gtop->prev_path);
478                    if (path == NULL)
479                            die("GPATH is corrupted.('%s' not found)", gtop->prev_path);
480            }
481    
482            for (i = 0; i < HASHBUCKETS; i++) {
483                    for (entry = gtop->htab[i]; entry != NULL; entry = next) {
484                            /*
485                             * extract method when class method definition.
486                             *
487                             * Ex: Class::method(...)
488                             *
489                             * key  = 'method'
490                             * data = 'Class::method  103 ./class.cpp ...'
491                             */
492                            key = entry->tag;
493                            if (gtop->flags & GTAGS_EXTRACTMETHOD) {
494                                    if ((key = locatestring(entry->tag, ".", MATCH_LAST)) != NULL)
495                                            key++;
496                                    else if ((key = locatestring(entry->tag, "::", MATCH_LAST)) != NULL)
497                                            key += 2;
498                                    else
499                                            key = entry->tag;
500                            }
501                            lno_array = varray_assign(entry->vb, 0, 0);
502                            qsort(lno_array, entry->vb->length, sizeof(int), compare_lno);
503                            strbuf_reset(gtop->sb);
504                            strbuf_puts(gtop->sb, entry->tag);
505                            strbuf_putc(gtop->sb, ' ');
506                            strbuf_puts(gtop->sb, path);
507                            strbuf_putc(gtop->sb, ' ');
508                            savelen = strbuf_getlen(gtop->sb);
509                            for (j = 0; j < entry->vb->length; j++) {
510                                    if ((gtop->flags & GTAGS_UNIQUE) && j > 0
511                                        && lno_array[j - 1] == lno_array[j])
512                                            continue;
513                                    if (strbuf_getlen(gtop->sb) > savelen)
514                                            strbuf_putc(gtop->sb, ',');
515                                    strbuf_putn(gtop->sb, lno_array[j]);
516                                    if (strbuf_getlen(gtop->sb) > DBOP_PAGESIZE / 4) {
517                                            dbop_put(gtop->dbop, key, strbuf_value(gtop->sb));
518                                            strbuf_setlen(gtop->sb, savelen);
519                                    }
520                            }
521                            if (strbuf_getlen(gtop->sb) > savelen)
522                                    dbop_put(gtop->dbop, key, strbuf_value(gtop->sb));
523                            varray_close(entry->vb);
524                            next = entry->next;
525                            free(entry);
526                    }
527                    gtop->htab[i] = NULL;
528            }
529    }
530    /*
531   * gtags_add: add tags belonging to the path list into tag file.   * gtags_add: add tags belonging to the path list into tag file.
532   *   *
533   *      i)      gtop    descripter of GTOP   *      i)      gtop    descripter of GTOP
# Line 438  gtags_add(gtop, comline, path_list, flag Line 547  gtags_add(gtop, comline, path_list, flag
547          STRBUF *sb = strbuf_open(0);          STRBUF *sb = strbuf_open(0);
548          STRBUF *ib = strbuf_open(MAXBUFLEN);          STRBUF *ib = strbuf_open(MAXBUFLEN);
549          const char *path, *end;          const char *path, *end;
550            int path_num;
551    
552            gtop->flags = flags;
553          /*          /*
554           * add path index if not yet.           * add path index if not yet.
555           */           */
556          path = strbuf_value(path_list);          path = strbuf_value(path_list);
557          end = path + strbuf_getlen(path_list);          end = path + strbuf_getlen(path_list);
558            path_num = 0;
559          while (path < end) {          while (path < end) {
560                  gpath_put(path);                  gpath_put(path);
561                    path_num++;
562                  path += strlen(path) + 1;                  path += strlen(path) + 1;
563          }          }
564          /*          /*
# Line 455  gtags_add(gtop, comline, path_list, flag Line 568  gtags_add(gtop, comline, path_list, flag
568          /*          /*
569           * Compact format.           * Compact format.
570           */           */
571          if (gtop->format & GTAGS_COMPACT) {          if ((gtop->format & GTAGS_COMPACT) != 0
572                  strbuf_puts(sb, "| gnusort -k3,3 -k 1,1 -k 2,2n");              && locatestring(comline, "gtags-parser", MATCH_FIRST) == NULL
573                  if (flags & GTAGS_UNIQUE)              && path_num > 1)
574                          strbuf_puts(sb, " -u");                  strbuf_puts(sb, "| gnusort -k3,3");
         }  
575  #ifdef DEBUG  #ifdef DEBUG
576          if (flags & GTAGS_DEBUG)          if (flags & GTAGS_DEBUG)
577                  fprintf(stderr, "gtags_add() executing '%s'\n", strbuf_value(sb));                  fprintf(stderr, "gtags_add() executing '%s'\n", strbuf_value(sb));
# Line 662  void Line 774  void
774  gtags_close(gtop)  gtags_close(gtop)
775          GTOP *gtop;          GTOP *gtop;
776  {  {
777          if (gtop->format & GTAGS_PATHINDEX || gtop->mode != GTAGS_READ)          if (gtop->htab) {
778                  gpath_close();                  if (gtop->prev_path[0])
779          if (gtop->sb && gtop->prev_tag[0])                          gtop_flush_htab(gtop);
780                  dbop_put(gtop->dbop, gtop->prev_tag, strbuf_value(gtop->sb));                  free(gtop->htab);
781            }
782          if (gtop->sb)          if (gtop->sb)
783                  strbuf_close(gtop->sb);                  strbuf_close(gtop->sb);
784          if (gtop->ib)          if (gtop->ib)
785                  strbuf_close(gtop->ib);                  strbuf_close(gtop->ib);
786            if (gtop->format & GTAGS_PATHINDEX || gtop->mode != GTAGS_READ)
787                    gpath_close();
788          dbop_close(gtop->dbop);          dbop_close(gtop->dbop);
789          free(gtop);          free(gtop);
790  }  }

Legend:
Removed from v.1.70  
changed lines
  Added in v.1.71

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