Exemplo n.º 1
0
/**
 *  Skip through the text to a matching "#endif" or "#else" or
 *  "#elif*def".  We do this when we are skipping code due to a failed
 *  "#if*def" test.
 */
static char *
skip_to_else_end(char * start)
{
    char * scan = start;
    char * res;

    for (;;) {
        scan = next_directive(scan);

        switch (find_directive(scan)) {
        case DIR_ELSE:
            /*
             *  We found an "else" directive for an "ifdef"/"ifndef"
             *  that we were skipping over.  Start processing the text.
             *  Let the @code{DIR_ENDIF} advance the scanning pointer.
             */
            ifdef_lvl++;
            /* FALLTHROUGH */

        case DIR_ENDIF:
        {
            /*
             * We reached the end of the "ifdef"/"ifndef" (or transitioned to
             * process-the-text mode via "else").  Start processing the text.
             */
            char * pz = strchr(scan, NL);
            if (pz != NULL)
                 res = pz+1;
            else res = scan + strlen(scan);
            goto leave_func;
        }

        case DIR_IF:
            skip_if_block = true;
            scan = skip_to_endif(scan);
            skip_if_block = false;
            break;

        case DIR_IFDEF:
        case DIR_IFNDEF:
            scan = skip_to_endif(scan);
            break;

        default:
            /*
             *  We either don't know what it is or we do not care.
             */
            break;
        }  /* switch (find_directive(scan)) */
    }

 leave_func:
    cctx->scx_line += count_lines(start, res);
    return res;
}
Exemplo n.º 2
0
/**
 *  Skip through the text to a matching "#endif".  We do this when we
 *  have processed the allowable text (found an "#else" after
 *  accepting the preceding text) or when encountering a "#if*def"
 *  while skipping a block of text due to a failed test.
 */
static char *
skip_to_endif(char * start)
{
    bool   skipping_if = skip_if_block;
    char * scan = start;
    char * dirv_end;

    for (;;) {
        scan = next_directive(scan);

        switch (find_directive(scan)) {
        case DIR_ENDIF:
        {
            /*
             *  We found the endif we are interested in
             */
            char * pz = strchr(scan, NL);
            if (pz != NULL)
                 dirv_end = pz+1;
            else dirv_end = scan + strlen(scan);
            goto leave_func;
        }

        case DIR_ELIF:
            if (! skip_if_block)
                AG_ABEND(ELIF_CONTEXT_MSG);
            break;

        case DIR_IF:
            skip_if_block = true;
            /* FALLTHROUGH */

        case DIR_IFDEF:
        case DIR_IFNDEF:
            /*
             *  We found a nested conditional, so skip to endif nested, too.
             */
            scan = skip_to_endif(scan);
            skip_if_block = skipping_if;
            break;

        default:
            /*
             *  We do not care what we found
             */
            break; /* ignore it */
        }  /* switch (find_directive(scan)) */
    }

 leave_func:
    cctx->scx_line += count_lines(start, dirv_end);
    return dirv_end;
}
Exemplo n.º 3
0
/**
 *  Skip through the text to a "#endmac".
 */
static char *
skip_to_endmac(char * start)
{
    char * scan = start;
    char * res;

    for (;;) {
        scan = next_directive(scan);

        if (find_directive(scan) == DIR_ENDMAC) {
            /*
             *  We found the endmac we are interested in
             */
            char * pz = strchr(scan, NL);
            if (pz != NULL)
                 res = pz+1;
            else res = scan + strlen(scan);
            break;
        }
    }

    cctx->scx_line += count_lines(start, res);
    return res;
}
Exemplo n.º 4
0
/* Return one whole line from the file into buf which holds at most n
   characters, for subsequent processing. Returns integer status. This
   routine also does all the "intelligent" work like processing cpp
   directives and so on. Note that often the routine is called
   recursively and no cpp directives are printed. */
int cpp_read_line(gmx_cpp_t *handlep, int n, char buf[])
{
    gmx_cpp_t   handle = (gmx_cpp_t)*handlep;
    int         i, nn, len, status;
    const char *ptr, *ptr2;
    char       *name;
    char       *dname, *dval;
    gmx_bool    bEOF;

    if (!handle)
    {
        return eCPP_INVALID_HANDLE;
    }
    if (!handle->fp)
    {
        return eCPP_FILE_NOT_OPEN;
    }

    bEOF = feof(handle->fp);
    if (!bEOF)
    {
        /* Read the actual line now. */
        if (fgets2(buf, n-1, handle->fp) == NULL)
        {
            /* Recheck EOF, since we could have been at the end before
             * the fgets2 call, but we need to read past the end to know.
             */
            bEOF = feof(handle->fp);
            if (!bEOF)
            {
                /* Something strange happened, fgets returned NULL,
                 * but we are not at EOF.
                 */
                return eCPP_UNKNOWN;
            }
        }
    }

    if (bEOF)
    {
        if (handle->parent == NULL)
        {
            return eCPP_EOF;
        }
        cpp_close_file(handlep);
        *handlep      = handle->parent;
        handle->child = NULL;
        return cpp_read_line(handlep, n, buf);
    }
    else
    {
        if (n > handle->line_len)
        {
            handle->line_len = n;
            srenew(handle->line, n);
        }
        strcpy(handle->line, buf);
        handle->line_nr++;
    }
    /* Now we've read a line! */
    if (debug)
    {
        fprintf(debug, "%s : %4d : %s\n", handle->fn, handle->line_nr, buf);
    }

    /* Process directives if this line contains one */
    if (find_directive(buf, &dname, &dval))
    {
        status = process_directive(handlep, dname, dval);
        if (status != eCPP_OK)
        {
            return status;
        }
        /* Don't print lines with directives, go on to the next */
        return cpp_read_line(handlep, n, buf);
    }

    /* Check whether we're not ifdeffed out. The order of this statement
       is important. It has to come after #ifdef, #else and #endif, but
       anything else should be ignored. */
    if (is_ifdeffed_out(handle))
    {
        return cpp_read_line(handlep, n, buf);
    }

    /* Check whether we have any defines that need to be replaced. Note
       that we have to use a best fit algorithm, rather than first come
       first go. We do this by sorting the defines on length first, and
       then on alphabetical order. */
    for (i = 0; (i < ndef); i++)
    {
        if (defs[i].def)
        {
            nn  = 0;
            ptr = buf;
            while ((ptr = strstrw(ptr, defs[i].name)) != NULL)
            {
                nn++;
                ptr += strlen(defs[i].name);
            }
            if (nn > 0)
            {
                len = strlen(buf) + nn*max(4, 4+strlen(defs[i].def)-strlen(defs[i].name));
                snew(name, len);
                ptr = buf;
                while ((ptr2 = strstrw(ptr, defs[i].name)) != NULL)
                {
                    strncat(name, ptr, (int)(ptr2-ptr));
                    strcat(name, defs[i].def);
                    ptr = ptr2 + strlen(defs[i].name);
                }
                strcat(name, ptr);
                strcpy(buf, name);
                sfree(name);
            }
        }
    }

    return eCPP_OK;
}