Esempio n. 1
0
File: find.c Progetto: kosaki/gtags
/*
 * find_read_traverse: read path without GPATH.
 *
 *	r)		path
 */
char *
find_read_traverse(void)
{
	static char val[MAXPATHLEN];
	char path[MAXPATHLEN];
	struct stack_entry *curp = varray_assign(stack, current_entry, 1);

	for (;;) {
		while (curp->p < curp->end) {
			char type = *(curp->p);
			const char *unit = curp->p + 1;

			curp->p += strlen(curp->p) + 1;

			/*
			 * Skip files described in the skip list.
			 */
				/* makepath() returns unsafe module local area. */
			strlimcpy(path, makepath(dir, unit, NULL), sizeof(path));
			if (type == 'd')
				strcat(path, "/");
			if (skipthisfile(path))
				continue;
			if (type == 'f') {
				/*
				 * Skip the following:
				 * o directory
				 * o file which does not exist
				 * o dead symbolic link
				 */
				if (!test("f", path)) {
					if (test("d", path))
						warning("'%s' is a directory. (Ignored)", path);
					else
						warning("'%s' not found. (Ignored)", path);
					continue;
				}
				/*
				 * GLOBAL cannot treat path which includes blanks.
				 * It will be improved in the future.
				 */
				if (!allow_blank && locatestring(path, " ", MATCH_FIRST)) {
					warning("'%s' ignored, because it includes blank.", &path[2]);
					continue;
				}
				/*
				 * A blank at the head of path means
				 * other than source file.
				 */
				if (regexec(suff, path, 0, 0, 0) == 0) {
					/* source file */
					strlimcpy(val, path, sizeof(val));
				} else {
					/* other file like 'Makefile' */
					val[0] = ' ';
					strlimcpy(&val[1], path, sizeof(val) - 1);
				}
				val[sizeof(val) - 1] = '\0';
				return val;
			}
			if (type == 'd') {
				STRBUF *sb = strbuf_open(0);
				char *dirp = curp->dirp;

				strcat(dirp, unit);
				strcat(dirp, "/");
				if (getdirs(dir, sb) < 0) {
					warning("cannot open directory '%s'. (Ignored)", dir);
					strbuf_close(sb);
					*(curp->dirp) = 0;
					continue;
				}
				/*
				 * Push stack.
				 */
				curp = varray_assign(stack, ++current_entry, 1);
				curp->dirp = dirp + strlen(dirp);
				curp->sb = sb;
				curp->start = curp->p = strbuf_value(sb);
				curp->end   = curp->start + strbuf_getlen(sb);
			}
		}
		strbuf_close(curp->sb);
		curp->sb = NULL;
		if (current_entry == 0)
			break;
		/*
		 * Pop stack.
		 */
		curp = varray_assign(stack, --current_entry, 0);
		*(curp->dirp) = 0;
	}
	find_eof = 1;
	return NULL;
}
Esempio n. 2
0
File: find.c Progetto: kosaki/gtags
/*
 * find_read_filelist: read path from file
 *
 *	r)		path
 */
static char *
find_read_filelist(void)
{
	STATIC_STRBUF(ib);
	static char buf[MAXPATHLEN + 1];
	static char *path;

	strbuf_clear(ib);
	for (;;) {
		path = strbuf_fgets(ib, ip, STRBUF_NOCRLF);
		if (path == NULL) {
			/* EOF */
			find_eof = 1;
			return NULL;
		}
		if (*path == '\0') {
			/* skip empty line.  */
			continue;
		}
		/*
		 * Lines which start with ". " are considered to be comments.
		 */
		if (*path == '.' && *(path + 1) == ' ')
			continue;
		/*
		 * Skip the following:
		 * o directory
		 * o file which does not exist
		 * o dead symbolic link
		 */
		if (!test("f", path)) {
			if (test("d", path))
				warning("'%s' is a directory. (Ignored)", path);
			else
				warning("'%s' not found. (Ignored)", path);
			continue;
		}
		/*
		 * normalize path name.
		 *
		 *	rootdir  /a/b/
		 *	buf      /a/b/c/d.c -> c/d.c -> ./c/d.c
		 */
		if (normalize(path, rootdir, cwddir, buf, sizeof(buf)) == NULL) {
			warning("'%s' is out of source tree. (Ignored)", path);
			continue;
		}
		path = buf;
		/*
		 * GLOBAL cannot treat path which includes blanks.
		 * It will be improved in the future.
		 */
		if (!allow_blank && locatestring(path, " ", MATCH_LAST)) {
			warning("'%s' ignored, because it includes blank.", path + 2);
			continue;
		}
		if (skipthisfile(path))
			continue;
		/*
		 * A blank at the head of path means
		 * other than source file.
		 */
		if (regexec(suff, path, 0, 0, 0) != 0)
			*--path = ' ';
		return path;
	}
}
Esempio n. 3
0
/**
 * incremental: incremental update
 *
 *	@param[in]	dbpath	dbpath directory
 *	@param[in]	root	root directory of source tree
 *	@return		0: not updated, 1: updated
 */
int
incremental(const char *dbpath, const char *root)
{
    STATISTICS_TIME *tim;
    struct stat statp;
    time_t gtags_mtime;
    STRBUF *addlist = strbuf_open(0);
    STRBUF *deletelist = strbuf_open(0);
    STRBUF *addlist_other = strbuf_open(0);
    IDSET *deleteset, *findset;
    int updated = 0;
    const char *path;
    unsigned int id, limit;

    tim = statistics_time_start("Time of inspecting %s and %s.", dbname(GTAGS), dbname(GRTAGS));
    if (vflag) {
        fprintf(stderr, " Tag found in '%s'.\n", dbpath);
        fprintf(stderr, " Incremental updating.\n");
    }
    /*
     * 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, 2) < 0)
        die("GPATH not found.");
    /*
     * deleteset:
     *	The list of the path name which should be deleted from GPATH.
     * findset:
     *	The list of the path name which exists in the current project.
     *	A project is limited by the --file option.
     */
    deleteset = idset_open(gpath_nextkey());
    findset = idset_open(gpath_nextkey());
    total = 0;
    /*
     * Make add list and delete list for update.
     */
    if (single_update) {
        int type;
        const char *fid;

        if (skipthisfile(single_update))
            goto exit;
        if (test("b", single_update))
            goto exit;
        fid = gpath_path2fid(single_update, &type);
        if (fid == NULL) {
            /* new file */
            type = issourcefile(single_update) ? GPATH_SOURCE : GPATH_OTHER;
            if (type == GPATH_OTHER)
                strbuf_puts0(addlist_other, single_update);
            else {
                strbuf_puts0(addlist, single_update);
                total++;
            }
        } else {
            /* update file */
            if (type == GPATH_OTHER)
                goto exit;
            idset_add(deleteset, atoi(fid));
            strbuf_puts0(addlist, single_update);
            total++;
        }
    } else {
        if (file_list)
            find_open_filelist(file_list, root);
        else
            find_open(NULL);
        while ((path = find_read()) != NULL) {
            const char *fid;
            int n_fid = 0;
            int other = 0;

            /* a blank at the head of path means 'NOT SOURCE'. */
            if (*path == ' ') {
                if (test("b", ++path))
                    continue;
                other = 1;
            }
            if (stat(path, &statp) < 0)
                die("stat failed '%s'.", path);
            fid = gpath_path2fid(path, NULL);
            if (fid) {
                n_fid = atoi(fid);
                idset_add(findset, n_fid);
            }
            if (other) {
                if (fid == NULL)
                    strbuf_puts0(addlist_other, path);
            } else {
                if (fid == NULL) {
                    strbuf_puts0(addlist, path);
                    total++;
                } else if (gtags_mtime < statp.st_mtime) {
                    strbuf_puts0(addlist, path);
                    total++;
                    idset_add(deleteset, n_fid);
                }
            }
        }
        find_close();
        /*
         * make delete list.
         */
        limit = gpath_nextkey();
        for (id = 1; id < limit; id++) {
            char fid[MAXFIDLEN];
            int type;

            snprintf(fid, sizeof(fid), "%d", id);
            /*
             * This is a hole of GPATH. The hole increases if the deletion
             * and the addition are repeated.
             */
            if ((path = gpath_fid2path(fid, &type)) == NULL)
                continue;
            /*
             * The file which does not exist in the findset is treated
             * assuming that it does not exist in the file system.
             */
            if (type == GPATH_OTHER) {
                if (!idset_contains(findset, id) || !test("f", path) || test("b", path))
                    strbuf_puts0(deletelist, path);
            } else {
                if (!idset_contains(findset, id) || !test("f", path)) {
                    strbuf_puts0(deletelist, path);
                    idset_add(deleteset, id);
                }
            }
        }
    }
    statistics_time_end(tim);
    /*
     * execute updating.
     */
    if ((!idset_empty(deleteset) || strbuf_getlen(addlist) > 0) ||
            (strbuf_getlen(deletelist) + strbuf_getlen(addlist_other) > 0))
    {
        int db;
        updated = 1;
        tim = statistics_time_start("Time of updating %s and %s.", dbname(GTAGS), dbname(GRTAGS));
        if (!idset_empty(deleteset) || strbuf_getlen(addlist) > 0)
            updatetags(dbpath, root, deleteset, addlist);
        if (strbuf_getlen(deletelist) + strbuf_getlen(addlist_other) > 0) {
            const char *start, *end, *p;

            if (vflag)
                fprintf(stderr, "[%s] Updating '%s'.\n", now(), dbname(GPATH));
            /* gpath_open(dbpath, 2); */
            if (strbuf_getlen(deletelist) > 0) {
                start = strbuf_value(deletelist);
                end = start + strbuf_getlen(deletelist);

                for (p = start; p < end; p += strlen(p) + 1)
                    gpath_delete(p);
            }
            if (strbuf_getlen(addlist_other) > 0) {
                start = strbuf_value(addlist_other);
                end = start + strbuf_getlen(addlist_other);

                for (p = start; p < end; p += strlen(p) + 1) {
                    gpath_put(p, GPATH_OTHER);
                }
            }
            /* gpath_close(); */
        }
        /*
         * Update modification time of tag files
         * because they may have no definitions.
         */
        for (db = GTAGS; db < GTAGLIM; db++)
            utime(makepath(dbpath, dbname(db), NULL), NULL);
        statistics_time_end(tim);
    }
exit:
    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(addlist_other);
    gpath_close();
    idset_close(deleteset);
    idset_close(findset);

    return updated;
}