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

📄 tags.c

📁 nedit 是一款linux下的开发源码的功能强大的编辑器
💻 C
📖 第 1 页 / 共 5 页
字号:
            ParseFilename(tagFiles[i], filename, pathname);            if ((i<nMatches-1 && !strcmp(tagFiles[i],tagFiles[i+1])) ||                    (i>0 && !strcmp(tagFiles[i],tagFiles[i-1]))) {                if(*(tagSearch[i]) && (tagPosInf[i] != -1)) { /* etags */                    sprintf(temp,"%2d. %s%s %8i %s", i+1, pathname,                             filename, tagPosInf[i], tagSearch[i]);                } else if (*(tagSearch[i])) { /* ctags search expr */                    sprintf(temp,"%2d. %s%s          %s", i+1, pathname,                             filename, tagSearch[i]);                } else { /* line number only */                    sprintf(temp,"%2d. %s%s %8i", i+1, pathname, filename,                            tagPosInf[i]);                }            } else                 sprintf(temp,"%2d. %s%s",i+1,pathname,filename);            if (!(dupTagsList[i] = (char *) malloc(strlen(temp) + 1))) {                fprintf(stderr, "NEdit: findDef(): out of heap space!\n");                XBell(TheDisplay, 0);                return -1;            }            strcpy(dupTagsList[i],temp);        }        createSelectMenu(dialogParent, "Duplicate Tags", nMatches, dupTagsList);        for (i=0; i<nMatches; i++)            free(dupTagsList[i]);        free(dupTagsList);        return 1;    }    /*    **  No need for a dialog list, there is only one tag matching --    **  Go directly to the tag    */    if (searchMode == TAG)        editTaggedLocation( dialogParent, 0 );    else        showMatchingCalltip( dialogParent, 0 );    return 1;}/*      Callback function for the FindAll widget. Process the users response. */static void findAllCB(Widget parent, XtPointer client_data, XtPointer call_data){    int i;    char *eptr;        XmSelectionBoxCallbackStruct *cbs =             (XmSelectionBoxCallbackStruct *) call_data;    if (cbs->reason == XmCR_NO_MATCH)        return;    if (cbs->reason == XmCR_CANCEL) {        XtDestroyWidget(XtParent(parent));        return;    }        XmStringGetLtoR(cbs->value,XmFONTLIST_DEFAULT_TAG,&eptr);    if ((i = atoi(eptr)-1) < 0) {        XBell(TheDisplay, 0);        return;    }        if (searchMode == TAG)        editTaggedLocation( parent, i ); /* Open the file with the definition */    else        showMatchingCalltip( parent, i );        if (cbs->reason == XmCR_OK)        XtDestroyWidget(XtParent(parent));}/*      Window manager close-box callback for tag-collision dialog */static void findAllCloseCB(Widget parent, XtPointer client_data,        XtPointer call_data){    XtDestroyWidget(parent);}/* * Given a \0 terminated string and a position, advance the position * by n lines, where line separators (for now) are \n.  If the end of * string is reached before n lines, return the number of lines advanced, * else normally return -1. */static int moveAheadNLines( char *str, int *pos, int n ) {    int i=n;    while (str[*pos] != '\0' && n>0) {        if (str[*pos] == '\n')            --n;        ++(*pos);    }    if (n==0)        return -1;    else        return i-n;}    /*** Show the calltip specified by tagFiles[i], tagSearch[i], tagPosInf[i]** This reads from either a source code file (if searchMode == TIP_FROM_TAG)** or a calltips file (if searchMode == TIP).*/ static void showMatchingCalltip( Widget parent, int i ){    int startPos=0, fileLen, readLen, tipLen;    int endPos=0;    char *fileString;    FILE *fp;    struct stat statbuf;    char *message;        /* 1. Open the target file */    NormalizePathname(tagFiles[i]);    fp = fopen(tagFiles[i], "r");    if (fp == NULL) {        DialogF(DF_ERR, parent, 1, "Error opening File", "Error opening %s",                "Dismiss", tagFiles[i]);        return;    }    if (fstat(fileno(fp), &statbuf) != 0) {        fclose(fp);        DialogF(DF_ERR, parent, 1, "Error opening File", "Error opening %s",                "Dismiss", tagFiles[i]);        return;    }    /* 2. Read the target file */    /* Allocate space for the whole contents of the file (unfortunately) */    fileLen = statbuf.st_size;    fileString = XtMalloc(fileLen+1);  /* +1 = space for null */    if (fileString == NULL) {        fclose(fp);        DialogF(DF_ERR, parent, 1, "File too large",                "File is too large to load", "Dismiss");        return;    }    /* Read the file into fileString and terminate with a null */    readLen = fread(fileString, sizeof(char), fileLen, fp);    if (ferror(fp)) {        fclose(fp);        DialogF(DF_ERR, parent, 1, "Error reading File", "Error reading %s",                "Dismiss", tagFiles[i]);        XtFree(fileString);        return;    }    fileString[readLen] = 0;     /* Close the file */    if (fclose(fp) != 0) {        /* unlikely error */        DialogF(DF_WARN, parent, 1, "Error closing File",                "Unable to close file", "Dismiss");        /* we read it successfully, so continue */    }        /* 3. Search for the tagged location (set startPos) */    if (!*(tagSearch[i])) {        /* It's a line number, just go for it */        if ((moveAheadNLines( fileString, &startPos, tagPosInf[i]-1 )) >= 0) {            DialogF(DF_ERR, parent, 1, "Tags Error",                    "%s\n not long enough for definition to be on line %d",                    "Dismiss", tagFiles[i], tagPosInf[i]);            XtFree(fileString);            return;        }    } else {        startPos = tagPosInf[i];        if(!fakeRegExSearch(WidgetToWindow(parent), fileString, tagSearch[i],                &startPos, &endPos)){            DialogF(DF_WARN, parent, 1, "Tag not found",                    "Definition for %s\nnot found in %s", "OK", tagName,                    tagFiles[i]);            XtFree(fileString);            return;        }    }        if (searchMode == TIP) {        int dummy, found;                        /* 4. Find the end of the calltip (delimited by an empty line) */        endPos = startPos;        found = SearchString(fileString, "\\n\\s*\\n", SEARCH_FORWARD,                    SEARCH_REGEX, False, startPos, &endPos, &dummy, NULL,                     NULL, NULL);        if (!found) {            /* Just take 4 lines */            moveAheadNLines( fileString, &endPos, TIP_DEFAULT_LINES );            --endPos;  /* Lose the last \n */        }    } else {  /* Mode = TIP_FROM_TAG */        /* 4. Copy TIP_DEFAULT_LINES lines of text to the calltip string */        endPos = startPos;        moveAheadNLines( fileString, &endPos, TIP_DEFAULT_LINES );        /* Make sure not to overrun the fileString with ". . ." */        if (((size_t) endPos) <= (strlen(fileString)-5)) {            sprintf( &fileString[endPos], ". . ." );            endPos += 5;        }    }    /* 5. Copy the calltip to a string */    tipLen = endPos - startPos;    message = XtMalloc(tipLen+1);  /* +1 = space for null */    if (message == NULL)    {        DialogF(DF_ERR, parent, 1, "Out of Memory",                "Can't allocate memory for calltip message", "Dismiss");        XtFree(fileString);        return;    }    strncpy( message, &fileString[startPos], tipLen );    message[tipLen] = 0;        /* 6. Display it */    tagsShowCalltip( WidgetToWindow(parent), message );    XtFree(message);    XtFree(fileString);}/*  Open a new (or existing) editor window to the location specified in    tagFiles[i], tagSearch[i], tagPosInf[i] */static void editTaggedLocation( Widget parent, int i ) {    /* Globals: tagSearch, tagPosInf, tagFiles, tagName, textNrows,            WindowList */    int startPos, endPos, lineNum, rows;    char filename[MAXPATHLEN], pathname[MAXPATHLEN];    WindowInfo *windowToSearch;        ParseFilename(tagFiles[i],filename,pathname);    /* open the file containing the definition */    EditExistingFile(WindowList, filename, pathname, 0, NULL, False, NULL);    windowToSearch = FindWindowWithFile(filename, pathname);    if (windowToSearch == NULL) {        DialogF(DF_WARN, parent, 1, "File not found", "File %s not found", "OK",                tagFiles[i]);        return;    }    startPos=tagPosInf[i];        if(!*(tagSearch[i])) {        /* if the search string is empty, select the numbered line */        SelectNumberedLine(windowToSearch, startPos);        return;    }    /* search for the tags file search string in the newly opened file */    if(!fakeRegExSearch(windowToSearch, NULL, tagSearch[i], &startPos,            &endPos)){        DialogF(DF_WARN, windowToSearch->shell, 1, "Tag Error",                "Definition for %s\nnot found in %s", "OK", tagName,                tagFiles[i]);        return;    }    /* select the matched string */    BufSelect(windowToSearch->buffer, startPos, endPos);    /* Position it nicely in the window,        about 1/4 of the way down from the top */    lineNum = BufCountLines(windowToSearch->buffer, 0, startPos);    XtVaGetValues(windowToSearch->lastFocus, textNrows, &rows, NULL);    TextSetScroll(windowToSearch->lastFocus, lineNum - rows/4, 0);    TextSetCursorPos(windowToSearch->lastFocus, endPos);}/*      Create a Menu for user to select from the collided tags */static Widget createSelectMenu(Widget parent, char *label, int nArgs,        char *args[]){    int i;    char tmpStr[100];    Widget menu;    XmStringTable list;    XmString popupTitle;    int ac;    Arg csdargs[20];        list = (XmStringTable) XtMalloc(nArgs * sizeof(XmString *));    for (i=0; i<nArgs; i++)        list[i] = XmStringCreateSimple(args[i]);    sprintf(tmpStr,"Select File With TAG: %s",tagName);    popupTitle = XmStringCreateSimple(tmpStr);    ac = 0;    XtSetArg(csdargs[ac], XmNlistLabelString, popupTitle); ac++;    XtSetArg(csdargs[ac], XmNlistItems, list); ac++;    XtSetArg(csdargs[ac], XmNlistItemCount, nArgs); ac++;    XtSetArg(csdargs[ac], XmNvisibleItemCount, 12); ac++;    XtSetArg(csdargs[ac], XmNautoUnmanage, False); ac++;    menu = CreateSelectionDialog(parent,label,csdargs,ac);    XtUnmanageChild(XmSelectionBoxGetChild(menu, XmDIALOG_TEXT));    XtUnmanageChild(XmSelectionBoxGetChild(menu, XmDIALOG_HELP_BUTTON));    XtUnmanageChild(XmSelectionBoxGetChild(menu, XmDIALOG_SELECTION_LABEL));    XtAddCallback(menu, XmNokCallback, (XtCallbackProc)findAllCB, menu);    XtAddCallback(menu, XmNapplyCallback, (XtCallbackProc)findAllCB, menu);    XtAddCallback(menu, XmNcancelCallback, (XtCallbackProc)findAllCB, menu);    AddMotifCloseCallback(XtParent(menu), findAllCloseCB, NULL);    for (i=0; i<nArgs; i++)        XmStringFree(list[i]);    XtFree((char *)list);    XmStringFree(popupTitle);    ManageDialogCenteredOnPointer(menu);    return menu;}/*--------------------------------------------------------------------------   Reference-counted string hack; SJT 4/2000   This stuff isn't specific to tags, so it should be in it's own file.   However, I'm leaving it in here for now to reduce the diffs.      This could really benefit from using a real hash table.*/#define RCS_SIZE 10000struct rcs;struct rcs_stats{    int talloc, tshar, tgiveup, tbytes, tbyteshared;};struct rcs{    struct rcs *next;    char       *string;    int         usage;};static struct rcs       *Rcs[RCS_SIZE];static struct rcs_stats  RcsStats;/*** Take a normal string, create a shared string from it if need be,** and return pointer to that shared string.**** Returned strings are const because they are shared.  Do not modify them!*/static const char *rcs_strdup(const char *str){    int bucket;    size_t len;    struct rcs *rp;    struct rcs *prev = NULL;      char *newstr = NULL;        if (str == NULL)        return NULL;            bucket = hashAddr(str) % RCS_SIZE;    len = strlen(str);        RcsStats.talloc++;#if 0      /* Don't share if it won't save space.           Doesn't save anything - if we have lots of small-size objects,       it's beneifical to share them.  We don't know until we make a full       count.  My tests show that it's better to leave this out.  */    if (len <= sizeof(struct rcs))    {        new_str = strdup(str); /* GET RID OF strdup() IF EVER ENABLED (not ANSI) */         RcsStats.tgiveup++;        return;    }#endif    /* Find it in hash */    for (rp = Rcs[bucket]; rp; rp = rp->next)    {        if (!strcmp(str, rp->string))            break;        prev = rp;    }    if (rp)  /* It exists, return it and bump ref ct */    {        rp->usage++;        newstr = rp->string;        RcsStats.tshar++;        RcsStats.tbyteshared += len;    }    else     /* Doesn't exist, conjure up a new one. */    {        struct rcs *newrcs = malloc(sizeof(struct rcs));        newrcs->string = malloc(len+1);        strcpy(newrcs->string, str);        newrcs->usage = 1;        newrcs->next = NULL;        if (Rcs[bucket])            prev->next = newrcs;

⌨️ 快捷键说明

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