Example #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;
}
Example #2
0
/**
 *  This must follow an @code{#if}, @code{#ifdef} or @code{#ifndef}.
 *  If it follows the @code{#if}, then it will be ignored.  Otherwise,
 *  it will change the processing state to the reverse of what it was.
 */
char *
doDir_else(directive_enum_t id, char const * arg, char * scan_next)
{
    if (--ifdef_lvl < 0)
        return bad_dirv_ctx(id, arg, scan_next);

    return skip_to_endif(scan_next);
}
Example #3
0
/**
 *  @code{#if} expressions are not analyzed.  @strong{Everything} from here
 *  to the matching @code{#endif} is skipped.
 */
char *
doDir_if(directive_enum_t id, char const * arg, char * scan_next)
{
    skip_if_block = true;
    scan_next = skip_to_endif(scan_next);
    skip_if_block = false;
    (void)arg;
    (void)id;
    return scan_next;
}
Example #4
0
static void if_handle(state_t* state, match_t* match, bool* reprocess)
{
    list_t* result = ppparam_get(state);
    struct expr* expr = NULL;
    uint16_t value;
    bstring output;
    bool stopped_at_else;

    // Ensure the parameter format is correct.
    if (list_size(result) == 1 &&
            ((parameter_t*)list_get_at(result, 0))->type == EXPRESSION)
    {
        // Get the expression.
        expr = ((parameter_t*)list_get_at(result, 0))->expr;
        replace_state = state;
        value = expr_evaluate(expr, &if_define_replace, &dhalt_expression_exit_handler);
        replace_state = NULL;
        
        if (value)
        {
            output = skip_to_endif(state, true, &stopped_at_else);
            if (stopped_at_else)
                skip_to_endif(state, false, &stopped_at_else);
        }
        else
        {
            bassigncstr(output, "");
            skip_to_endif(state, true, &stopped_at_else);
            if (stopped_at_else)
            {
                output = skip_to_endif(state, false, &stopped_at_else);
            }
        }
        
        // print the output to the pre processor input
        ppimpl_printf(state, "%s", output->data);
    }
    else
        dhalt(ERR_PP_ASM_IF_PARAMETERS_INCORRECT, ppimpl_get_location(state));
    
    ppparam_free(result);
}
Example #5
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;
}