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

📄 tags.c

📁 nedit 是一款linux下的开发源码的功能强大的编辑器
💻 C
📖 第 1 页 / 共 5 页
字号:
        if (tf->loaded) {            if (stat(tf->filename,&statbuf) != 0) { /*  */                fprintf(stderr, TAG_STS_ERR_FMT, tf->filename);            } else {                      if (tf->date == statbuf.st_mtime) {                    /* current tags file tf is already loaded and up to date */                    continue;                 }            }            /* tags file has been modified, delete it's entries and reload it */            delTag(NULL,NULL,-2,NULL,-2,tf->index);        }        /* If we get here we have to try to (re-) load the tags file */        if (FileList == TipsFileList)            load_status = loadTipsFile(tf->filename, tf->index, 0);        else            load_status = loadTagsFile(tf->filename, tf->index, 0);        if(load_status) {            if (stat(tf->filename,&statbuf) != 0) {                if(!tf->loaded) {                    /* if tf->loaded == 1 we already have seen the error msg */                    fprintf(stderr, TAG_STS_ERR_FMT, tf->filename);                }            } else {                tf->date = statbuf.st_mtime;            }            tf->loaded = 1;        } else {            tf->loaded = 0;        }    }        t = getTag(name, search_type);        if (!t) {        return FALSE;    }   else {        *file = t->file;        *language = t->language;        *searchString = t->searchString;        *pos = t->posInf;        *path = t->path;        return TRUE;    }}/* ** This code path is followed if the request came from either** FindDefinition or FindDefCalltip.  This should probably be refactored.*/static int findDef(WindowInfo *window, const char *value, int search_type) {    static char tagText[MAX_TAG_LEN + 1];    const char *p;    char message[MAX_TAG_LEN+40];    int l, ml, status = 0;        searchMode = search_type;    l = strlen(value);    if (l <= MAX_TAG_LEN) {        /* should be of type text??? */        for (p = value; *p && isascii(*p); p++) {        }        if (!(*p)) {            ml = ((l < MAX_TAG_LEN) ? (l) : (MAX_TAG_LEN));            strncpy(tagText, value, ml);            tagText[ml] = '\0';            /* See if we can find the tip/tag */            status = findAllMatches(window, tagText);            /* If we didn't find a requested calltip, see if we can use a tag */            if (status == 0 && search_type == TIP && TagsFileList != NULL) {                searchMode = TIP_FROM_TAG;                status = findAllMatches(window, tagText);            }            if (status == 0) {                /* Didn't find any matches */                if (searchMode == TIP_FROM_TAG || searchMode == TIP) {                    sprintf(message, "No match for \"%s\" in calltips or tags.",                            tagName);                    tagsShowCalltip( window, message );                } else                {                    DialogF(DF_WARN, window->textArea, 1, "Tags",                            "\"%s\" not found in tags file%s", "OK", tagName,                            (TagsFileList && TagsFileList->next) ? "s" : "");                }            }        }        else {            fprintf(stderr, "NEdit: Can't handle non 8-bit text\n");            XBell(TheDisplay, 0);        }    }    else {        fprintf(stderr, "NEdit: Tag Length too long.\n");        XBell(TheDisplay, 0);    }    return status;}/*** Lookup the definition for the current primary selection the currently** loaded tags file and bring up the file and line that the tags file** indicates.*/void findDefinitionHelper(WindowInfo *window, Time time, const char *arg,                   int search_type){    if(arg)    {        findDef(window, arg, search_type);     }    else    {        searchMode = search_type;        XtGetSelectionValue(window->textArea, XA_PRIMARY, XA_STRING,                (XtSelectionCallbackProc)findDefCB, window, time);    }}/*** See findDefHelper*/void FindDefinition(WindowInfo *window, Time time, const char *arg){    findDefinitionHelper(window, time, arg, TAG);}/*** See findDefHelper*/void FindDefCalltip(WindowInfo *window, Time time, const char *arg){    /* Reset calltip parameters to reasonable defaults */    globAnchored = False;    globPos = -1;    globHAlign = TIP_LEFT;    globVAlign = TIP_BELOW;    globAlignMode = TIP_SLOPPY;    findDefinitionHelper(window, time, arg, TIP);}/* Callback function for FindDefinition */static void findDefCB(Widget widget, WindowInfo *window, Atom *sel,        Atom *type, char *value, int *length, int *format){    /* skip if we can't get the selection data, or it's obviously too long */    if (*type == XT_CONVERT_FAIL || value == NULL) {        XBell(TheDisplay, 0);    } else {        findDef(window, value, searchMode);    }    XtFree(value);}/* ** Try to display a calltip**  anchored:       If true, tip appears at position pos**  lookup:         If true, text is considered a key to be searched for in the**                  tip and/or tag database depending on search_type**  search_type:    Either TIP or TIP_FROM_TAG*/int ShowTipString(WindowInfo *window, char *text, Boolean anchored,        int pos, Boolean lookup, int search_type, int hAlign, int vAlign,        int alignMode) {    if (search_type == TAG) return 0;        /* So we don't have to carry all of the calltip alignment info around */    globAnchored = anchored;    globPos = pos;    globHAlign = hAlign;    globVAlign = vAlign;    globAlignMode = alignMode;        /* If this isn't a lookup request, just display it. */    if (!lookup)        return tagsShowCalltip(window, text);    else        return findDef(window, text, search_type);}/* store all of the info into a pre-allocated tags struct */static void setTag(tag *t, const char *name, const char *file,         int language, const char *searchString, int posInf,         const char *path){    t->name         = rcs_strdup(name);    t->file         = rcs_strdup(file);    t->language     = language;    t->searchString = rcs_strdup(searchString);    t->posInf       = posInf;    t->path         = rcs_strdup(path);}/*** ctags search expressions are literal strings with a search direction flag, ** line starting "^" and ending "$" delimiters. This routine translates them ** into NEdit compatible regular expressions and does the search.** Etags search expressions are plain literals strings, which ** ** If in_buffer is not NULL then it is searched instead of the window buffer.** In this case in_buffer should be an XtMalloc allocated buffer and the** caller is responsible for freeing it.*/static int fakeRegExSearch(WindowInfo *window, char *in_buffer,         const char *searchString, int *startPos, int *endPos){    int found, searchStartPos, dir, ctagsMode;    char *fileString, searchSubs[3*MAXLINE+3], *outPtr;    const char *inPtr;        if (in_buffer == NULL) {        /* get the entire (sigh) text buffer from the text area widget */        fileString = BufGetAll(window->buffer);    } else {        fileString = in_buffer;    }            /* determine search direction and start position */    if (*startPos != -1) { /* etags mode! */        dir = SEARCH_FORWARD;        searchStartPos = *startPos;        ctagsMode=0;    } else if (searchString[0] == '/') {        dir = SEARCH_FORWARD;        searchStartPos = 0;        ctagsMode=1;    } else if (searchString[0] == '?') {        dir = SEARCH_BACKWARD;        /* searchStartPos = window->buffer->length; */        searchStartPos = strlen(fileString);        ctagsMode=1;    } else {        fprintf(stderr, "NEdit: Error parsing tag file search string");        if(in_buffer == NULL)            XtFree(fileString);        return FALSE;    }    /* Build the search regex. */    outPtr=searchSubs;     if(ctagsMode) {         inPtr=searchString+1; /* searchString[0] is / or ? --> search dir */        if(*inPtr == '^') {            /* If the first char is a caret then it's a RE line start delim */            *outPtr++ = *inPtr++;        }    } else {  /* etags mode, no search dir spec, no leading caret */      inPtr=searchString;    }    while(*inPtr) {        if( (*inPtr=='\\' && inPtr[1]=='/') ||            (*inPtr=='\r' && inPtr[1]=='$' && !inPtr[2])          ) {          /* Remove:              - escapes (added by standard and exuberant ctags) from slashes             - literal CRs generated by standard ctags for DOSified sources          */          inPtr++;        } else if(strchr("()-[]<>{}.|^*+?&\\", *inPtr)                   || (*inPtr == '$' && (inPtr[1]||(!ctagsMode)))){            /* Escape RE Meta Characters to match them literally.               Don't escape $ if it's the last charcter of the search expr               in ctags mode; always escape $ in etags mode.             */            *outPtr++ = '\\';            *outPtr++ = *inPtr++;        } else if (isspace((unsigned char)*inPtr)) { /* col. multiple spaces */            *outPtr++ = '\\';            *outPtr++ = 's';            *outPtr++ = '+';            do { inPtr++ ; } while(isspace((unsigned char)*inPtr));        } else {              /* simply copy all other characters */            *outPtr++ = *inPtr++;        }    }    *outPtr=0; /* Terminate searchSubs */        found = SearchString(fileString, searchSubs, dir, SEARCH_REGEX,       	    False, searchStartPos, startPos, endPos, NULL, NULL, NULL);        if(!found && !ctagsMode) {        /* position of the target definition could have been drifted before           startPos, if nothing has been found by now try searching backward           again from startPos.        */        found = SearchString(fileString, searchSubs, SEARCH_BACKWARD,                 SEARCH_REGEX, False, searchStartPos, startPos, endPos, NULL,                 NULL, NULL);    }    /* free the text buffer copy returned from XmTextGetString */    if(in_buffer == NULL)        XtFree(fileString);        /* return the result */    if (found) {        /* *startPos and *endPos are set in SearchString*/        return TRUE;    } else {        /* startPos, endPos left untouched by SearchString if search failed. */        XBell(TheDisplay, 0);        return FALSE;    }}/*      Finds all matches and handles tag "collisions". Prompts user with a         list of collided tags in the hash table and allows the user to select        the correct one. */static int findAllMatches(WindowInfo *window, const char *string){    Widget dialogParent = window->textArea;    char filename[MAXPATHLEN], pathname[MAXPATHLEN];    char temp[32+2*MAXPATHLEN+MAXLINE];    const char *fileToSearch, *searchString, *tagPath;    char **dupTagsList;    int startPos, i, pathMatch=0, samePath=0, langMode, nMatches=0;    /* verify that the string is reasonable as a tag */    if (*string == '\0' || strlen(string) > MAX_TAG_LEN) {        XBell(TheDisplay, 0);        return -1;    }    tagName=string;    /* First look up all of the matching tags */    while (LookupTag(string, &fileToSearch, &langMode, &searchString, &startPos,                     &tagPath, searchMode)) {        /* Skip this tag if it has a language mode that doesn't match the             current language mode, but don't skip anything if the window is in            PLAIN_LANGUAGE_MODE. */        if (window->languageMode != PLAIN_LANGUAGE_MODE &&                 GetPrefSmartTags() && langMode != PLAIN_LANGUAGE_MODE &&                langMode != window->languageMode) {            string=NULL;            continue;        }        if (*fileToSearch == '/')             strcpy(tagFiles[nMatches], fileToSearch);        else             sprintf(tagFiles[nMatches],"%s%s",tagPath,fileToSearch);        strcpy(tagSearch[nMatches],searchString);        tagPosInf[nMatches]=startPos;        ParseFilename(tagFiles[nMatches], filename, pathname);        /* Is this match in the current file?  If so, use it! */        if (GetPrefSmartTags() && !strcmp(window->filename,filename)                               && !strcmp(window->path,pathname)   ) {            if (nMatches) {                strcpy(tagFiles[0],tagFiles[nMatches]);                strcpy(tagSearch[0],tagSearch[nMatches]);                tagPosInf[0]=tagPosInf[nMatches];            }            nMatches = 1;            break;        }        /* Is this match in the same dir. as the current file? */        if (!strcmp(window->path,pathname)) {            samePath++;            pathMatch=nMatches;        }        if (++nMatches >= MAXDUPTAGS) {            DialogF(DF_WARN, dialogParent, 1, "Tags",                    "Too many duplicate tags, first %d shown", "OK", MAXDUPTAGS);            break;        }        /* Tell LookupTag to look for more definitions of the same tag: */        string = NULL;     }    /* Did we find any matches? */    if (!nMatches) {        return 0;    }        /* Only one of the matches is in the same dir. as this file.  Use it. */    if (GetPrefSmartTags() && samePath == 1 && nMatches > 1) {        strcpy(tagFiles[0],tagFiles[pathMatch]);        strcpy(tagSearch[0],tagSearch[pathMatch]);        tagPosInf[0]=tagPosInf[pathMatch];        nMatches = 1;    }        /*  If all of the tag entries are the same file, just use the first.     */    if (GetPrefSmartTags()) {        for (i=1; i<nMatches; i++)             if (strcmp(tagFiles[i],tagFiles[i-1]))                break;        if (i==nMatches)             nMatches = 1;    }        if (nMatches>1) {        if (!(dupTagsList = (char **) malloc(sizeof(char *) * nMatches))) {            fprintf(stderr, "NEdit: findDef(): out of heap space!\n");            XBell(TheDisplay, 0);            return -1;        }        for (i=0; i<nMatches; i++) {

⌨️ 快捷键说明

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