📄 build.c
字号:
/* get the next source file name */ for (fileindex = firstfile; fileindex < lastfile; ++fileindex) { /* display the progress about every three seconds */ if (interactive == YES && fileindex % 10 == 0) { progress("Building symbol database", (long)fileindex, (long)lastfile); } /* if the old file has been deleted get the next one */ file = srcfiles[fileindex]; while (oldfile != NULL && strcmp(file, oldfile) > 0) { oldfile = getoldfile(); } /* if there isn't an old database or this is a new file */ if (oldfile == NULL || strcmp(file, oldfile) < 0) { crossref(file); ++built; } /* if this file was modified */ else if (lstat(file, &statstruct) == 0 && statstruct.st_mtime > reftime) { crossref(file); ++built; /* skip its old crossref so modifying the last source file does not cause all included files to be built. Unfortunately a new file that is alphabetically last will cause all included files to be build, but this is less likely */ oldfile = getoldfile(); } else { /* copy its cross-reference */ putfilename(file); if (invertedindex == YES) { copyinverted(); } else { copydata(); } ++copied; oldfile = getoldfile(); } } /* see if any included files were found */ if (lastfile == nsrcfiles) { break; } firstfile = lastfile; lastfile = nsrcfiles; if (invertedindex == YES) { srcoffset = myrealloc(srcoffset, (nsrcfiles + 1) * sizeof(long)); } /* sort the included file names */ qsort(&srcfiles[firstfile], (unsigned) (lastfile - firstfile), sizeof(char *), compare); } /* add a null file name to the trailing tab */ putfilename(""); dbputc('\n'); /* get the file trailer offset */ traileroffset = dboffset; /* output the source and include directory and file lists */ putlist(srcdirs, nsrcdirs); putlist(incdirs, nincdirs); putlist(srcfiles, nsrcfiles); if (fflush(newrefs) == EOF) { /* rewind doesn't check for write failure */ cannotwrite(newreffile); /* NOTREACHED */ } /* create the inverted index if requested */ if (invertedindex == YES) { char sortcommand[PATHLEN + 1]; if (fflush(postings) == EOF) { cannotwrite(temp1); /* NOTREACHED */ } (void) fstat(fileno(postings), &statstruct); (void) fclose(postings); (void) sprintf(sortcommand, "env LC_ALL=C sort -T %s %s", tmpdir, temp1); if ((postings = mypopen(sortcommand, "r")) == NULL) { (void) fprintf(stderr, "cscope: cannot open pipe to sort command\n"); cannotindex(); } else { if ((totalterms = invmake(newinvname, newinvpost, postings)) > 0) { movefile(newinvname, invname); movefile(newinvpost, invpost); } else { cannotindex(); } (void) mypclose(postings); } (void) unlink(temp1); (void) free(srcoffset); } /* rewrite the header with the trailer offset and final option list */ rewind(newrefs); putheader(newdir); (void) fclose(newrefs); /* close the old database file */ if (symrefs >= 0) { (void) close(symrefs); } if (oldrefs != NULL) { (void) fclose(oldrefs); } /* replace it with the new database file */ movefile(newreffile, reffile);} /* string comparison function for qsort */static intcompare(const void *arg_s1, const void *arg_s2){ const char **s1 = (const char **) arg_s1; const char **s2 = (const char **) arg_s2; return(strcmp(*s1, *s2));}/* seek to the trailer, in a given file */void seek_to_trailer(FILE *f) { if (fscanf(f, "%ld", &traileroffset) != 1) { posterr("cscope: cannot read trailer offset from file %s\n", reffile); myexit(1); } if (fseek(f, traileroffset, SEEK_SET) == -1) { posterr("cscope: cannot seek to trailer in file %s\n", reffile); myexit(1); }}/* get the next file name in the old cross-reference */static char *getoldfile(void){ static char file[PATHLEN + 1]; /* file name in old crossref */ if (blockp != NULL) { do { if (*blockp == NEWFILE) { skiprefchar(); putstring(file); if (file[0] != '\0') { /* if not end-of-crossref */ return(file); } return(NULL); } } while (scanpast('\t') != NULL); } return(NULL);}/* Free all storage allocated for filenames: */void free_newbuildfiles(void){ free(newinvname); free(newinvpost); free(newreffile);} /* output the cscope version, current directory, database format options, and the database trailer offset */static voidputheader(char *dir){ dboffset = fprintf(newrefs, "cscope %d %s", FILEVERSION, dir); if (compress == NO) { dboffset += fprintf(newrefs, " -c"); } if (invertedindex == YES) { dboffset += fprintf(newrefs, " -q %.10ld", totalterms); } else { /* leave space so if the header is overwritten without -q because writing the inverted index failed, the header is the same length */ dboffset += fprintf(newrefs, " "); } if (trun_syms == YES) { dboffset += fprintf(newrefs, " -T"); } dboffset += fprintf(newrefs, " %.10ld\n", traileroffset);#ifdef PRINTF_RETVAL_BROKEN dboffset = ftell(newrefs); #endif}/* put the name list into the cross-reference file */static voidputlist(char **names, int count){ int i, size = 0; (void) fprintf(newrefs, "%d\n", count); if (names == srcfiles) { /* calculate the string space needed */ for (i = 0; i < count; ++i) { size += strlen(names[i]) + 1; } (void) fprintf(newrefs, "%d\n", size); } for (i = 0; i < count; ++i) { if (fputs(names[i], newrefs) == EOF || putc('\n', newrefs) == EOF) { cannotwrite(newreffile); /* NOTREACHED */ } }}/* copy this file's symbol data */static voidcopydata(void){ char symbol[PATLEN + 1]; char *cp; setmark('\t'); cp = blockp; for (;;) { /* copy up to the next \t */ do { /* innermost loop optimized to only one test */ while (*cp != '\t') { dbputc(*cp++); } } while (*++cp == '\0' && (cp = readblock()) != NULL); dbputc('\t'); /* copy the tab */ /* get the next character */ if (*(cp + 1) == '\0') { cp = readblock(); } /* exit if at the end of this file's data */ if (cp == NULL || *cp == NEWFILE) { break; } /* look for an #included file */ if (*cp == INCLUDE) { blockp = cp; putinclude(symbol); writestring(symbol); setmark('\t'); cp = blockp; } } blockp = cp;}/* copy this file's symbol data and output the inverted index postings */static voidcopyinverted(void){ char *cp; char c; int type; /* reference type (mark character) */ char symbol[PATLEN + 1]; /* note: this code was expanded in-line for speed */ /* while (scanpast('\n') != NULL) { */ /* other macros were replaced by code using cp instead of blockp */ cp = blockp; for (;;) { setmark('\n'); do { /* innermost loop optimized to only one test */ while (*cp != '\n') { dbputc(*cp++); } } while (*++cp == '\0' && (cp = readblock()) != NULL); dbputc('\n'); /* copy the newline */ /* get the next character */ if (*(cp + 1) == '\0') { cp = readblock(); } /* exit if at the end of this file's data */ if (cp == NULL) { break; } switch (*cp) { case '\n': lineoffset = dboffset + 1; continue; case '\t': dbputc('\t'); blockp = cp; type = getrefchar(); switch (type) { case NEWFILE: /* file name */ return; case INCLUDE: /* #included file */ putinclude(symbol); goto output; } dbputc(type); skiprefchar(); putstring(symbol); goto output; } c = *cp; if (c & 0200) { /* digraph char? */ c = dichar1[(c & 0177) / 8]; } /* if this is a symbol */ if (isalpha((unsigned char)c) || c == '_') { blockp = cp; putstring(symbol); type = ' '; output: putposting(symbol, type); writestring(symbol); if (blockp == NULL) { return; } cp = blockp; } } blockp = cp;}/* replace the old file with the new file */static voidmovefile(char *new, char *old){ (void) unlink(old); if (rename(new, old) == -1) { (void) myperror("cscope"); posterr("cscope: cannot rename file %s to file %s\n", new, old); myexit(1); }}/* process the #included file in the old database */static voidputinclude(char *s){ dbputc(INCLUDE); skiprefchar(); putstring(s); incfile(s + 1, s);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -