⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tags.c

📁 nedit 是一款linux下的开发源码的功能强大的编辑器
💻 C
📖 第 1 页 / 共 5 页
字号:
**    Nedit.tags: <tagfile1>:<tagfile2>**  Returns True if all files were found in the FileList or loaded successfully,**  FALSE otherwise.*/int AddTagsFile(const char *tagSpec, int file_type){    tagFile *t;    int added=1;    struct stat statbuf;    char *filename;    char pathName[MAXPATHLEN];    char *tmptagSpec;    tagFile *FileList;        /* To prevent any possible segfault */    if (tagSpec == NULL) {        fprintf(stderr, "nedit: Internal Error!\n"                "  Passed NULL pointer to AddTagsFile!\n");        return FALSE;    }        searchMode = file_type;    if (searchMode == TAG)        FileList = TagsFileList;    else        FileList = TipsFileList;    tmptagSpec = (char *) malloc(strlen(tagSpec)+1);    strcpy(tmptagSpec, tagSpec);        for (filename = strtok(tmptagSpec,":"); filename; filename = strtok(NULL,":")) {        if (*filename != '/') {          strcpy(pathName, GetCurrentDir());            strcat(pathName,"/");            strcat(pathName,filename);        } else {            strcpy(pathName,filename);        }        NormalizePathname(pathName);        CompressPathname(pathName);        for (t = FileList; t && strcmp(t->filename,pathName); t = t->next);        if (t) {            added=1;            continue;        }        if (stat(pathName,&statbuf) != 0) {            /* Problem reading this tags file.  Return FALSE */            added = 0;            continue;        }        t = (tagFile *) malloc(sizeof(tagFile));        t->filename = STRSAVE(pathName);        t->loaded = 0;        t->date = statbuf.st_mtime;        t->index = ++tagFileIndex;        t->next = FileList;        FileList = setFileListHead(t, file_type );    }    free(tmptagSpec);    updateMenuItems();    if (added)        return TRUE;    else       return FALSE;}/* Un-manage a colon-delimited set of tags files  * Return TRUE if all files were found in the FileList and unloaded, FALSE * if any file was not found in the FileList. */int DeleteTagsFile(const char *tagSpec, int file_type){       tagFile *t, *last;    tagFile *FileList;    char pathName[MAXPATHLEN], *tmptagSpec, *filename;    int removed;        /* To prevent any possible segfault */    if (tagSpec == NULL) {        fprintf(stderr, "nedit: Internal Error!\n"                "  Passed NULL pointer to DeleteTagsFile!\n");        return FALSE;    }        searchMode = file_type;    if (searchMode == TAG)        FileList = TagsFileList;    else        FileList = TipsFileList;    tmptagSpec = (char *) malloc(strlen(tagSpec)+1);    strcpy(tmptagSpec, tagSpec);    removed=1;    for (filename = strtok(tmptagSpec,":"); filename;             filename = strtok(NULL,":")) {        if (*filename != '/') {          strcpy(pathName, GetCurrentDir());            strcat(pathName,"/");            strcat(pathName,filename);        } else {            strcpy(pathName,filename);        }        NormalizePathname(pathName);        CompressPathname(pathName);        for (last=NULL,t = FileList; t; last = t,t = t->next) {            if (strcmp(t->filename, pathName))                continue;            if (t->loaded)                delTag(NULL,NULL,-2,NULL,-2,t->index);            if (last) last->next = t->next;            else FileList = setFileListHead(t->next, file_type);            free(t->filename);            free(t);            updateMenuItems();            break;        }        /* If any file can't be removed, return false */        if (!t)            removed = 0;    }    if (removed)        return TRUE;    else        return FALSE;}/* ** Update the "Find Definition", "Unload Tags File", "Show Calltip", ** and "Unload Calltips File" menu items in the existing windows. */static void updateMenuItems() {    WindowInfo *w;     Boolean tipStat=FALSE, tagStat=FALSE;        if (TipsFileList) tipStat=TRUE;    if (TagsFileList) tagStat=TRUE;        for (w=WindowList; w!=NULL; w=w->next) {        XtSetSensitive(w->showTipItem, tipStat || tagStat);        XtSetSensitive(w->unloadTipsMenuItem, tipStat);        XtSetSensitive(w->findDefItem, tagStat);        XtSetSensitive(w->unloadTagsMenuItem, tagStat);    }}/* ** Scans one <line> from a ctags tags file (<index>) in tagPath.** Return value: Number of tag specs added.*/static int scanCTagsLine(const char *line, const char *tagPath, int index) {    char name[MAXLINE], searchString[MAXLINE];    char file[MAXPATHLEN];    char *posTagREEnd, *posTagRENull;    int  nRead, pos;    nRead = sscanf(line, "%s\t%s\t%[^\n]", name, file, searchString);    if (nRead != 3)         return 0;    if ( *name == '!' )        return 0;    /*     ** Guess the end of searchString:    ** Try to handle original ctags and exuberant ctags format:     */    if(searchString[0] == '/' || searchString[0] == '?') {        pos=-1; /* "search expr without pos info" */                /* Situations: /<ANY expr>/\0             **             ?<ANY expr>?\0          --> original ctags         **             /<ANY expr>/;"  <flags>        **             ?<ANY expr>?;"  <flags> --> exuberant ctags         */        posTagREEnd = strrchr(searchString, ';');        posTagRENull = strchr(searchString, 0);         if(!posTagREEnd || (posTagREEnd[1] != '"') ||             (posTagRENull[-1] == searchString[0])) {            /*  -> original ctags format = exuberant ctags format 1 */            posTagREEnd = posTagRENull;        } else {            /* looks like exuberant ctags format 2 */            *posTagREEnd = 0;        }        /*         ** Hide the last delimiter:        **   /<expression>/    becomes   /<expression>        **   ?<expression>?    becomes   ?<expression>        ** This will save a little work in fakeRegExSearch.        */        if(posTagREEnd > (searchString+2)) {            posTagREEnd--;            if(searchString[0] == *posTagREEnd)                *posTagREEnd=0;        }    } else {        pos=atoi(searchString);        *searchString=0;    }    /* No ability to read language mode right now */    return addTag(name, file, PLAIN_LANGUAGE_MODE, searchString, pos, tagPath,             index);}  /*  * Scans one <line> from an etags (emacs) tags file (<index>) in tagPath. * recLevel = current recursion level for tags file including * file = destination definition file. possibly modified. len=MAXPATHLEN! * Return value: Number of tag specs added. */static int scanETagsLine(const char *line, const char * tagPath, int index,                         char * file, int recLevel) {    char name[MAXLINE], searchString[MAXLINE];    char incPath[MAXPATHLEN];    int pos, len;    char *posDEL, *posSOH, *posCOM;        /* check for destination file separator  */    if(line[0]==12) { /* <np> */        *file=0;        return 0;    }        /* check for standard definition line */    posDEL=strchr(line, '\177');    posSOH=strchr(line, '\001');    posCOM=strrchr(line, ',');    if(*file && posDEL && (posSOH > posDEL) && (posCOM > posSOH)) {        /* exuberant ctags -e style  */        len=Min(MAXLINE-1, posDEL - line);        strncpy(searchString, line, len);        searchString[len]=0;        len=Min(MAXLINE-1, (posSOH - posDEL) - 1);        strncpy(name, posDEL + 1, len);        name[len]=0;        pos=atoi(posCOM+1);        /* No ability to set language mode for the moment */        return addTag(name, file, PLAIN_LANGUAGE_MODE, searchString, pos,                 tagPath, index);    }     if (*file && posDEL && (posCOM > posDEL)) {        /* old etags style, part  name<soh>  is missing here! */        len=Min(MAXLINE-1, posDEL - line);        strncpy(searchString, line, len);        searchString[len]=0;        /* guess name: take the last alnum (plus _) part of searchString */        while(--len >= 0) {            if( isalnum((unsigned char)searchString[len]) ||                     (searchString[len] == '_'))                break;        }        if(len<0)            return 0;        pos=len;        while (pos >= 0 && (isalnum((unsigned char)searchString[pos]) ||                 (searchString[pos] == '_')))            pos--;        strncpy(name, searchString + pos + 1, len - pos);        name[len - pos] = 0; /* name ready */        pos=atoi(posCOM+1);        return addTag(name, file, PLAIN_LANGUAGE_MODE, searchString, pos,                 tagPath, index);    }    /* check for destination file spec */    if(*line && posCOM) {        len=Min(MAXPATHLEN-1, posCOM - line);        strncpy(file, line, len);        file[len]=0;        /* check if that's an include file ... */        if(!(strncmp(posCOM+1, "include", 7))) {            if(*file != '/') {                if((strlen(tagPath) + strlen(file)) >= MAXPATHLEN) {                    fprintf(stderr, "tags.c: MAXPATHLEN overflow\n");                    *file=0; /* invalidate */                    return 0;                }                strcpy(incPath, tagPath);                strcat(incPath, file);                CompressPathname(incPath);                return(loadTagsFile(incPath, index, recLevel+1));            } else {                return(loadTagsFile(file, index, recLevel+1));            }        }    }    return 0;}/* Tag File Type */typedef enum {   TFT_CHECK, TFT_ETAGS, TFT_CTAGS} TFT;/*  ** Loads tagsFile into the hash table. ** Returns the number of added tag specifications.*/static int loadTagsFile(const char *tagsFile, int index, int recLevel){    FILE *fp = NULL;    char line[MAXLINE];    char file[MAXPATHLEN], tagPath[MAXPATHLEN];    char resolvedTagsFile[MAXPATHLEN+1];    int nTagsAdded=0;    int tagFileType = TFT_CHECK;        if(recLevel > MAX_TAG_INCLUDE_RECURSION_LEVEL) {        return 0;    }    /* the path of the tags file must be resolved to find the right files:     * definition source files are (in most cases) specified relatively inside     * the tags file to the tags files directory.     */    if(!ResolvePath(tagsFile, resolvedTagsFile)) {        return 0;    }    /* Open the file */    if ((fp = fopen(resolvedTagsFile, "r")) == NULL) {       return 0;    }    ParseFilename(resolvedTagsFile, NULL, tagPath);    /* Read the file and store its contents */    while (fgets(line, MAXLINE, fp)) {        /* This might take a while if you have a huge tags file (like I do)..           keep the windows up to date and post a busy cursor so the user           doesn't think we died. */        AllWindowsBusy("Loading tags file...");        /* the first character in the file decides if the file is treat as           etags or ctags file.         */        if(tagFileType==TFT_CHECK) {            if(line[0]==12)  /* <np> */                tagFileType=TFT_ETAGS;            else                tagFileType=TFT_CTAGS;        }        if(tagFileType==TFT_CTAGS) {            nTagsAdded += scanCTagsLine(line, tagPath, index);        } else {            nTagsAdded += scanETagsLine(line, tagPath, index, file, recLevel);        }    }    fclose(fp);        AllWindowsUnbusy();    return nTagsAdded;}/*** Given a tag name, lookup the file and path of the definition** and the proper search string. Returned strings are pointers** to internal storage which are valid until the next loadTagsFile call.**** Invocation with name != NULL (containing the searched definition) **    --> returns first definition of  name** Successive invocation with name == NULL**    --> returns further definitions (resulting from multiple tags files)**** Return Value: TRUE:  tag spec found**               FALSE: no (more) definitions found.*/#define TAG_STS_ERR_FMT "NEdit: Error getting status for tag file %s\n"int LookupTag(const char *name, const char **file, int *language,              const char **searchString, int * pos, const char **path,              int search_type){    tag *t;    tagFile *tf;    struct stat statbuf;    tagFile *FileList;    int load_status;        searchMode = search_type;    if (searchMode == TIP)        FileList = TipsFileList;    else        FileList = TagsFileList;        /*    ** Go through the list of all tags Files:    **   - load them (if not already loaded)    **   - check for update of the tags file and reload it in that case    **   - save the modification date of the tags file    **    ** Do this only as long as name != NULL, not for sucessive calls     ** to find multiple tags specs.    **    */        for (tf = FileList; tf && name; tf = tf->next) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -