Exemple #1
0
/*
 * handle_specials
 */
int
handle_specials (parse_ctx_t pctx, void *vctx, quotelevel_t ql, lextype_t curlt)
{
    macroctx_t ctx = vctx;
    strdesc_t *str;
    lexseq_t result;

    if (ctx->curexp == 0) {
        log_signal(parser_logctx(pctx), parser_curpos(pctx), STC__INVMACFUN);
        return 1;
    }
    switch (curlt) {
        case LEXTYPE_LXF_COUNT:
            // our internal counter is 1-based; %COUNT is zero-based.
            str = string_printf(parser_strctx(pctx), 0, "%ld", ctx->curexp->count-1);
            parser_insert(pctx, parser_lexeme_create(pctx, LEXTYPE_NUMERIC, str));
            string_free(parser_strctx(pctx), str);
            break;
        case LEXTYPE_LXF_LENGTH:
            str = string_printf(parser_strctx(pctx), 0, "%ld", ctx->curexp->nactuals);
            parser_insert(pctx, parser_lexeme_create(pctx, LEXTYPE_NUMERIC, str));
            string_free(parser_strctx(pctx), str);
            break;
        case LEXTYPE_LXF_REMAINING:
            lexseq_init(&result);
            lexseq_copy(parser_lexmemctx(pctx), &result, &ctx->curexp->remaining);
            parser_insert_seq(pctx, &result);
            break;
        default:
            break;
    }

    return 1;

} /* handle_specials */
Exemple #2
0
static void sig_exit (int sig)
{
	log_signal (sig);
	server_quit = 1;

	// FIXME (JCF): pthread_*() are not async-signal-safe and
	//              should not be used within signal handlers.
	if (!pthread_equal (server_tid, pthread_self()))
		pthread_kill (server_tid, sig);
}
Exemple #3
0
static void sig_chld (int sig LOGIT_ONLY)
{
	int saved_errno;
	pid_t rc;

	log_signal (sig);

	saved_errno = errno;
	do {
		rc = waitpid (-1, NULL, WNOHANG);
	} while (rc > 0);
	errno = saved_errno;
}
Exemple #4
0
/*
 * lexer_insert_seq
 *
 * Inserts a sequence of lexemes at the front of the stream.
 */
void
lexer_insert_seq (lexer_ctx_t ctx, lexseq_t *seq)
{
    lexchain_t *chain = ctx->chain;

    if (seq == 0 || lexseq_length(seq) == 0) {
        return;
    }
    if (chain == 0) {
        chain = lexchain_alloc(ctx);
        if (chain == 0) {
            log_signal(ctx->logctx, 0, STC__OUTOFMEM, "lexer_insert_seq");
            return;
        }
        chain->nextchain = ctx->chain;
        ctx->chain = chain;
    }
    lexseq_prepend(&chain->seq, seq);

} /* lexer_insert_seq_internal */
Exemple #5
0
/*
 * lexer_popen
 * Insert a programmatic input source at the front of the stream.
 */
int
lexer_popen (lexer_ctx_t ctx, void *vinfn, void *fnctx)
{
    scan_input_fn infn = vinfn;
    lexchain_t *chain = lexchain_alloc(ctx);

    if (chain == 0) {
        log_signal(ctx->logctx, 0, STC__OUTOFMEM, "lexer_popen");
        return 0;
    }
    chain->strm = scan_popen(ctx->scnctx, infn, fnctx);
    if (chain->strm == 0) {
        lexchain_free(ctx, chain);
        return 0;
    }
    chain->filename_index = -1;
    chain->nextchain = ctx->chain;
    ctx->chain = chain;
    ctx->atend = 0;
    return 1;

} /* lexer_popen */
Exemple #6
0
/*
 * lexer_insert
 *
 * Insert a single lexeme to the front of the stream.
 */
void
lexer_insert (lexer_ctx_t ctx, lexeme_t *lex)
{
    lexchain_t *chain = ctx->chain;

    // The static ones should never be inserted, and
    // just ignore nulls.
    if (lex == &errlex || lex == &endlex || lex == 0) {
        return;
    }

    if (chain == 0) {
        chain = lexchain_alloc(ctx);
        if (chain == 0) {
            log_signal(ctx->logctx, 0, STC__OUTOFMEM, "lexer_insert");
            return;
        }
        chain->nextchain = ctx->chain;
        ctx->chain = chain;
    }
    lexseq_inshead(&chain->seq, lex);

} /* lexer_insert */
Exemple #7
0
/*
 * lexer_fopen
 * Insert a new file at the front of the stream.
 */
int
lexer_fopen (lexer_ctx_t ctx, const char *fname, size_t fnlen,
             char **actnamep)
{
    lexchain_t *chain = lexchain_alloc(ctx);
    char *actname;

    if (chain == 0) {
        log_signal(ctx->logctx, 0, STC__OUTOFMEM, "lexer_fopen");
        return 0;
    }
    chain->strm = scan_fopen(ctx->scnctx, fname, fnlen, &actname);
    if (chain->strm == 0) {
        lexchain_free(ctx, chain);
        return 0;
    }
    chain->filename_index = filename_lookup(ctx, actname, strlen(actname), 0);
    chain->nextchain = ctx->chain;
    ctx->chain = chain;
    if (actnamep != 0) *actnamep = actname;
    ctx->atend = 0;
    return 1;

} /* lexer_fopen */
Exemple #8
0
/*
 * lexer___next
 *
 * Returns the next lexeme in the stream.
 * If 'erroneof' is set, reaching the end of a file (not the
 * end of the stream) should be considered an error condition --
 * this happens when we're in the middle of parsing a lexical
 * conditional or a macro definition; they must be wholly contained
 * within a single file.
 *
 * This is the internal version that handles both lexer_next
 * and lexer_peek processing.
 */
static lexeme_t *
lexer___next (lexer_ctx_t ctx, int erroneof, int peek, textpos_t *posp)
{
    lexeme_t *lex = 0;
    lextype_t lextype;
    strdesc_t *tok;
    unsigned int column;
    char *cp;

    if (ctx == 0) {
        return &errlex;
    }

    if (ctx->atend) {
        return &endlex;
    }

    while (ctx->chain != 0) {
        lexchain_t *chain = ctx->chain;
        lex = (peek ? lexseq_head(&chain->seq) : lexseq_remhead(&chain->seq));
        if (lex != 0) {
            break;
        }
        if (chain->strm != 0) {
            scantype_t type;
            unsigned int sflags;

            sflags = (erroneof ? SCAN_M_ERRONEOF : 0) |
                     (ctx->signok ? SCAN_M_SIGNOK : 0);

            type = scan_getnext(chain->strm, sflags, &tok,
                                &chain->curline, &column);
            if (!scan_ok(type)) {
                textpos_t pos = textpos_create(chain->filename_index,
                                               chain->curline, column);
                log_signal(ctx->logctx, pos, STC__INVTOKEN);
                lex = &errlex;
                string_free(ctx->strctx, tok);
                break;
            }
            if (!peek && posp != 0) {
                *posp = textpos_create(chain->filename_index, chain->curline, column);
            }
            if (type == SCANTYPE_END) {
                scan_close(chain->strm);
                chain->strm = 0;
                ctx->chain = chain->nextchain;
                lexchain_free(ctx, chain);
                if (ctx->chain == 0) {
                    lex = &endlex;
                    ctx->atend = 1;
                    string_free(ctx->strctx, tok);
                    break;
                }
                string_free(ctx->strctx, tok);
                continue;
            }
            switch (type) {
                case SCANTYPE_DECLITERAL:
                    lextype = LEXTYPE_NUMERIC;
                    ctx->signok = 0;
                    break;
                case SCANTYPE_QUOTEDSTRING:
                    lextype = LEXTYPE_STRING;
                    ctx->signok = 1;
                    break;
                case SCANTYPE_OPERATOR:
                    cp = strchr(operators, *tok->ptr);
                    lextype = opertypes[cp-operators];
                    ctx->signok = 1;
                    break;
                case SCANTYPE_PUNCTUATION:
                    cp = strchr(delimiters, *tok->ptr);
                    lextype = delimtypes[cp-delimiters];
                    ctx->signok = (strchr(")>]", *tok->ptr) == 0);
                    break;
                case SCANTYPE_IDENTIFIER:
                    lextype = LEXTYPE_NAME;
                    ctx->signok = 0;
                    break;
                default:
                    lextype = LEXTYPE_NONE;
                    break;
            }
            if (lextype == LEXTYPE_NONE) {
                lex = &errlex;
            } else {
                lex = lexeme_create(ctx->lexctx, lextype, tok);
                if (peek) {
                    lexseq_inshead(&chain->seq, lex);
                }
            }
            string_free(ctx->strctx, tok);
            break;
        } else {
            ctx->chain = chain->nextchain;
            lexchain_free(ctx, chain);
            if (ctx->chain == 0) {
                lex = &endlex;
                ctx->atend = 1;
                break;
            }
        }
    }
    return lex;

} /* lexer___next */
Exemple #9
0
static int
list_switch_handler (parse_ctx_t pctx, void *vctx, lextype_t dtype, lexeme_t *swlex)
{
    lstgctx_t ctx = vctx;
    lexeme_t *lex;
    liststate_t *newstate;
    int i;

    if (!parser_expect(pctx, QL_NORMAL, LEXTYPE_DELIM_LPAR, 0, 1)) {
        log_signal(parser_logctx(pctx), parser_curpos(pctx), STC__DELIMEXP, "(");
        return 0;
    }

    if (parser_scope_get(pctx) != ctx->cur_state->this_scope) {
        newstate = malloc(sizeof(liststate_t));
        if (newstate == 0) {
            log_signal(parser_logctx(pctx), parser_curpos(pctx), STC__INTCMPERR,
                       "list_switch_handler");
            return 0;
        }
        memcpy(newstate, ctx->cur_state, sizeof(liststate_t));
        newstate->next = ctx->cur_state;
        newstate->this_scope = parser_scope_get(pctx);
        ctx->cur_state = newstate;
    } else {
        newstate = 0;
    }

    while (1) {
        i = parser_expect_oneof(pctx, QL_NORMAL, lopt_lextypes,
                                sizeof(lopt_lextypes)/sizeof(lopt_lextypes[0]), &lex, 1);
        if (i < 0) {
            log_signal(parser_logctx(pctx), parser_curpos(pctx), STC__LSTOPTEXP);
            break;
        }
        if (lexeme_type(lex) == LEXTYPE_DCL_REQUIRE) {
            ctx->cur_state->listopts[LISTOPT_REQ] = 1;
        } else if (lexeme_type(lex) == LEXTYPE_DCL_LIBRARY) {
            ctx->cur_state->listopts[LISTOPT_LIB] = 1;
        } else {
            value_toggle_dispatch(pctx, ctx, dtype, lexeme_ctx_get(lex));
        }
        lexeme_free(parser_lexmemctx(pctx), lex);
        if (parser_expect(pctx, QL_NORMAL, LEXTYPE_DELIM_RPAR, 0, 1)) {
            return 1;
        }
        if (!parser_expect(pctx, QL_NORMAL, LEXTYPE_DELIM_COMMA, 0, 1)) {
            log_signal(parser_logctx(pctx), parser_curpos(pctx), STC__DELIMEXP, ",");
            break;
        }
    } /* while */

    // We break out of the loop only on error

    if (newstate != 0) {
        ctx->cur_state = newstate->next;
        free(newstate);
    }
    parser_skip_to_delim(pctx, LEXTYPE_DELIM_RPAR);
    return 0;

} /* list_switch_handler */