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

📄 tags.c

📁 nedit 是一款linux下的开发源码的功能强大的编辑器
💻 C
📖 第 1 页 / 共 5 页
字号:
        else            Rcs[bucket] = newrcs;                    newstr = newrcs->string;    }    RcsStats.tbytes += len;    return newstr;}/*** Decrease the reference count on a shared string.  When the reference** count reaches zero, free the master string.*/static void rcs_free(const char *rcs_str){    int bucket;    struct rcs *rp;    struct rcs *prev = NULL;    if (rcs_str == NULL)        return;            bucket = hashAddr(rcs_str) % RCS_SIZE;    /* find it in hash */    for (rp = Rcs[bucket]; rp; rp = rp->next)    {        if (rcs_str == rp->string)            break;        prev = rp;    }    if (rp)  /* It's a shared string, decrease ref count */    {        rp->usage--;                if (rp->usage < 0) /* D'OH! */        {            fprintf(stderr, "NEdit: internal error deallocating shared string.");            return;        }        if (rp->usage == 0)  /* Last one- free the storage */        {            free(rp->string);            if (prev)                prev->next = rp->next;            else                Rcs[bucket] = rp->next;            free(rp);        }    }    else    /* Doesn't appear to be a shared string */    {        fprintf(stderr, "NEdit: attempt to free a non-shared string.");        return;    }}/******************************************************************** *           Functions for loading Calltips files                   * ********************************************************************/enum tftoken_types { TF_EOF, TF_BLOCK, TF_VERSION, TF_INCLUDE, TF_LANGUAGE,                      TF_ALIAS, TF_ERROR, TF_ERROR_EOF };/* A wrapper for SearchString */static int searchLine(char *line, const char *regex) {    int dummy1, dummy2;    return SearchString(line, regex, SEARCH_FORWARD, SEARCH_REGEX,                             False, 0, &dummy1, &dummy2, NULL, NULL, NULL);}/* Check if a line has non-ws characters */static Boolean lineEmpty(const char *line) {    while (*line && *line != '\n') {        if (*line != ' ' && *line != '\t')            return False;        ++line;    }    return True;}/* Remove trailing whitespace from a line */static void rstrip( char *dst, const char *src ) {    int wsStart, dummy2;    /* Strip trailing whitespace */    if(SearchString(src, "\\s*\\n", SEARCH_FORWARD, SEARCH_REGEX,                         False, 0, &wsStart, &dummy2, NULL, NULL, NULL)) {        if(dst != src)            memcpy(dst, src, wsStart);        dst[wsStart] = 0;    } else        if(dst != src)            strcpy(dst, src);}/* ** Get the next block from a tips file.  A block is a \n\n+ delimited set of** lines in a calltips file.  All of the parameters except <fp> are return** values, and most have different roles depending on the type of block** that is found.  **      header:     Depends on the block type**      body:       Depends on the block type.  Used to return a new **                  dynamically allocated string.**      blkLine:    Returns the line number of the first line of the block**                  after the "* xxxx *" line. **      currLine:   Used to keep track of the current line in the file.*/static int nextTFBlock(FILE *fp, char *header, char **body, int *blkLine,         int *currLine) {    /* These are the different kinds of tokens */    const char *commenTF_regex = "^\\s*\\* comment \\*\\s*$";    const char *version_regex  = "^\\s*\\* version \\*\\s*$";    const char *include_regex  = "^\\s*\\* include \\*\\s*$";    const char *language_regex = "^\\s*\\* language \\*\\s*$";    const char *alias_regex    = "^\\s*\\* alias \\*\\s*$";    char line[MAXLINE], *status;    int dummy1;    int code;        /* Skip blank lines and comments */    while(1) {        /* Skip blank lines */        while((status=fgets(line, MAXLINE, fp))) {            ++(*currLine);            if(!lineEmpty( line ))                 break;        }        /* Check for error or EOF */        if(!status)             return TF_EOF;        /* We've got a non-blank line -- is it a comment block? */        if( !searchLine(line, commenTF_regex) )             break;                /* Skip the comment (non-blank lines) */        while((status=fgets(line, MAXLINE, fp))) {            ++(*currLine);            if(lineEmpty( line ))                 break;        }                if(!status)             return TF_EOF;    }        /* Now we know it's a meaningful block */    dummy1 = searchLine(line, include_regex);    if( dummy1 || searchLine(line, alias_regex) ) {        /* INCLUDE or ALIAS block */        int incLen, incPos, i, incLines;                /* fprintf(stderr, "Starting include/alias at line %i\n", *currLine); */        if(dummy1)            code = TF_INCLUDE;        else {            code = TF_ALIAS;            /* Need to read the header line for an alias */            status=fgets(line, MAXLINE, fp);            ++(*currLine);            if (!status)                 return TF_ERROR_EOF;            if (lineEmpty( line )) {                fprintf( stderr, "nedit: Warning: empty '* alias *' "                        "block in calltips file.\n" );                return TF_ERROR;            }            rstrip(header, line);        }        incPos = ftell(fp);        *blkLine = *currLine + 1; /* Line of first actual filename/alias */        if (incPos < 0)             return TF_ERROR;        /* Figure out how long the block is */        while((status=fgets(line, MAXLINE, fp))) {            ++(*currLine);            if(lineEmpty( line ))                 break;        }        incLen = ftell(fp) - incPos;        incLines = *currLine - *blkLine;        /* Correct currLine for the empty line it read at the end */        --(*currLine);        if (incLines == 0) {            fprintf( stderr, "nedit: Warning: empty '* include *' or"                    " '* alias *' block in calltips file.\n" );            return TF_ERROR;        }        /* Make space for the filenames/alias sources */        *body = (char *)malloc(incLen+1);        if (!*body)             return TF_ERROR;        *body[0]=0;        if (fseek(fp, incPos, SEEK_SET) != 0) {            free (*body);            return TF_ERROR;        }        /* Read all the lines in the block */        /* fprintf(stderr, "Copying lines\n"); */        for (i=0; i<incLines; i++) {            status = fgets(line, MAXLINE, fp);            if (!status) {                free (*body);                return TF_ERROR_EOF;            }            rstrip(line,line);            if(i)                 strcat(*body, ":");            strcat(*body, line);        }        /* fprintf(stderr, "Finished include/alias at line %i\n", *currLine); */    }        else if( searchLine(line, language_regex) ) {        /* LANGUAGE block */        status=fgets(line, MAXLINE, fp);        ++(*currLine);        if (!status)             return TF_ERROR_EOF;        if (lineEmpty( line )) {            fprintf( stderr, "nedit: Warning: empty '* language *' block in calltips file.\n" );            return TF_ERROR;        }        *blkLine = *currLine;        rstrip(header, line);        code = TF_LANGUAGE;    }    else if( searchLine(line, version_regex) ) {        /* VERSION block */        status=fgets(line, MAXLINE, fp);        ++(*currLine);        if (!status)             return TF_ERROR_EOF;        if (lineEmpty( line )) {            fprintf( stderr, "nedit: Warning: empty '* version *' block in calltips file.\n" );            return TF_ERROR;        }        *blkLine = *currLine;        rstrip(header, line);        code = TF_VERSION;    }    else {        /* Calltip block */        /*  The first line is the key, the rest is the tip.             Strip trailing whitespace. */        rstrip(header, line);                status=fgets(line, MAXLINE, fp);        ++(*currLine);        if (!status)             return TF_ERROR_EOF;        if (lineEmpty( line )) {            fprintf( stderr, "nedit: Warning: empty calltip block:\n"                     "   \"%s\"\n", header);            return TF_ERROR;        }        *blkLine = *currLine;        *body = strdup(line);        code = TF_BLOCK;    }        /* Skip the rest of the block */    dummy1 = *currLine;    while(fgets(line, MAXLINE, fp)) {        ++(*currLine);        if (lineEmpty( line ))             break;    }        /* Warn about any unneeded extra lines (which are ignored). */    if (dummy1+1 < *currLine && code != TF_BLOCK) {        fprintf( stderr, "nedit: Warning: extra lines in language or version block ignored.\n" );    }        return code;}/* A struct for describing a calltip alias */typedef struct _alias {    char *dest;    char *sources;    struct _alias *next;} tf_alias;/*** Allocate a new alias, copying dest and stealing sources.  This may** seem strange but that's the way it's called */static tf_alias *new_alias(const char *dest, char *sources) {    tf_alias *alias;        /* fprintf(stderr, "new_alias: %s <- %s\n", dest, sources); */    /* Allocate the alias */    alias = (tf_alias *)malloc( sizeof(tf_alias) );    if(!alias)         return NULL;    /* Fill it in */    alias->dest = (char*)malloc( strlen(dest)+1 );    if(!(alias->dest))        return NULL;    strcpy( alias->dest, dest );    alias->sources = sources;    return alias;}/* Deallocate a linked-list of aliases */static void free_alias_list(tf_alias *alias) {    tf_alias *tmp_alias;    while(alias) {        tmp_alias = alias->next;        free(alias->dest);        free(alias->sources);        free(alias);        alias = tmp_alias;    }}/*** Load a calltips file and insert all of the entries into the global tips** database.  Each tip is essentially stored as its filename and the line** at which it appears--the exact same way ctags indexes source-code.  That's** why calltips and tags share so much code.*/static int loadTipsFile(const char *tipsFile, int index, int recLevel){    FILE *fp = NULL;    char header[MAXLINE];    char *body, *tipIncFile;    char tipPath[MAXPATHLEN];    char resolvedTipsFile[MAXPATHLEN+1];    int nTipsAdded=0, langMode = PLAIN_LANGUAGE_MODE, oldLangMode;    int currLine=0, code, blkLine;    tf_alias *aliases=NULL, *tmp_alias;        if(recLevel > MAX_TAG_INCLUDE_RECURSION_LEVEL) {        fprintf(stderr, "nedit: Warning: Reached recursion limit before loading calltips file:\n\t%s\n", tipsFile);        return 0;    }        /* find the tips file */#ifndef VMS    /* Allow ~ in Unix filenames */    strncpy(tipPath, tipsFile, MAXPATHLEN);    /* ExpandTilde is destructive */    ExpandTilde(tipPath);    if(!ResolvePath(tipPath, resolvedTipsFile))        return 0;#else    if(!ResolvePath(tipsFile, resolvedTipsFile))        return 0;#endif    /* Get the path to the tips file */    ParseFilename(resolvedTipsFile, NULL, tipPath);    /* Open the file */    if ((fp = fopen(resolvedTipsFile, "r")) == NULL)       return 0;    while( 1 ) {        code = nextTFBlock(fp, header, &body, &blkLine, &currLine);        if( code == TF_ERROR_EOF ) {            fprintf(stderr,"nedit: Warning: unexpected EOF in calltips file.\n");            break;        }        if( code == TF_EOF )             break;                switch (code) {            case TF_BLOCK:                /* Add the calltip to the global hash table.                    For the moment I'm just using line numbers because I don't                    want to have to deal with adding escape characters for                    regex metacharacters that might appear in the string */                nTipsAdded += addTag(header, resolvedTipsFile, langMode, "",                         blkLine, tipPath, index);                free( body );                break;            case TF_INCLUDE:                /* nextTFBlock returns a colon-separated list of tips files                    in body */                for(tipIncFile=strtok(body,":"); tipIncFile;                         tipIncFile=strtok(NULL,":")) {                    /* fprintf(stderr,                        "nedit: DEBUG: including tips file '%s'\n",                        tipIncFile); */                    nTipsAdded += loadTipsFile( tipIncFile, index, recLevel+1);                }                free( body );              

⌨️ 快捷键说明

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