Ejemplo n.º 1
0
static void param_declarator(node_t ** ty, struct token **id)
{
    if (token->id == '*') {
        node_t *pty = ptr_decl();
        prepend_type(ty, pty);
    }

    if (token->id == '(') {
        if (first_decl(lookahead())) {
            abstract_declarator(ty);
        } else {
            node_t *type1 = *ty;
            node_t *rtype = NULL;
            expect('(');
            param_declarator(&rtype, id);
            expect(')');
            if (token->id == '(' || token->id == '[') {
                node_t *faty;
                cc_assert(id);
                if (*id) {
                    faty = func_or_array(false, NULL);
                } else {
                    faty = func_or_array(true, NULL);
                }
                attach_type(&faty, type1);
                attach_type(&rtype, faty);
            }
            *ty = rtype;
        }
    } else if (token->id == '[') {
        abstract_declarator(ty);
    } else if (token->id == ID) {
        declarator(ty, id, NULL);
    }
}
Ejemplo n.º 2
0
static void fields(node_t * sym)
{
    int follow[] = {INT, CONST, '}', IF, 0};
    node_t *sty = SYM_TYPE(sym);

    if (!first_decl(token)) {
        error("expect type name or qualifiers");
        return;
    }

    struct vector *v = vec_new();
    do {
        node_t *basety = specifiers(NULL, NULL);

        for (;;) {
            node_t *field = new_field();
            if (token->id == ':') {
                bitfield(field);
                FIELD_TYPE(field) = basety;
            } else {
                node_t *ty = NULL;
                struct token *id = NULL;
                declarator(&ty, &id, NULL);
                attach_type(&ty, basety);
                if (token->id == ':')
                    bitfield(field);
                FIELD_TYPE(field) = ty;
                if (id) {
                    for (int i = 0; i < vec_len(v); i++) {
                        node_t *f = vec_at(v, i);
                        if (FIELD_NAME(f) &&
                                !strcmp(FIELD_NAME(f), id->name)) {
                            errorf(id->src,
                                   "redefinition of '%s'",
                                   id->name);
                            break;
                        }
                    }
                    FIELD_NAME(field) = id->name;
                    AST_SRC(field) = id->src;
                }
            }

            vec_push(v, field);
            if (token->id != ',')
                break;
            expect(',');
            ensure_field(field, vec_len(v), false);
        }

        match(';', follow);
        ensure_field(vec_tail(v), vec_len(v),
                     isstruct(sty) && !first_decl(token));
    } while (first_decl(token));

    TYPE_FIELDS(sty) = (node_t **) vtoa(v);
    set_typesize(sty);
}
Ejemplo n.º 3
0
static node_t *func_or_array(bool abstract, int *params)
{
    node_t *ty = NULL;
    int follow[] = { '[', ID, IF, 0 };

    for (; token->id == '(' || token->id == '[';) {
        if (token->id == '[') {
            node_t *atype;
            expect('[');
            atype = arrays(abstract);
            match(']', follow);
            attach_type(&ty, atype);
        } else {
            node_t *ftype = func_type();
            expect('(');
            TYPE_PARAMS(ftype) = parameters(ftype, params);
            match(')', follow);
            attach_type(&ty, ftype);
        }
    }

    return ty;
}
Ejemplo n.º 4
0
static void declarator(node_t ** ty, struct token **id, int *params)
{
    int follow[] = { ',', '=', IF, 0 };

    cc_assert(ty && id);

    if (token->id == '*') {
        node_t *pty = ptr_decl();
        prepend_type(ty, pty);
    }

    if (token->id == ID) {
        *id = token;
        expect(ID);
        if (token->id == '[' || token->id == '(') {
            node_t *faty = func_or_array(false, params);
            prepend_type(ty, faty);
        }
    } else if (token->id == '(') {
        node_t *type1 = *ty;
        node_t *rtype = NULL;
        expect('(');
        declarator(&rtype, id, params);
        match(')', follow);
        if (token->id == '[' || token->id == '(') {
            node_t *faty = func_or_array(false, params);
            attach_type(&faty, type1);
            attach_type(&rtype, faty);
        } else {
            attach_type(&rtype, type1);
        }
        *ty = rtype;
    } else {
        error("expect identifier or '('");
    }
}
Ejemplo n.º 5
0
static struct vector *decls(declfun_p * dcl)
{
    struct vector *v = vec_new();
    node_t *basety;
    int sclass, fspec;
    int level = SCOPE;
    int follow[] = {STATIC, INT, CONST, IF, '}', 0};

    basety = specifiers(&sclass, &fspec);
    if (token->id == ID || token->id == '*' || token->id == '(') {
        struct token *id = NULL;
        node_t *ty = NULL;
        int params = 0;        // for functioness

        // declarator
        if (level == GLOBAL)
            declarator(&ty, &id, &params);
        else
            declarator(&ty, &id, NULL);
        attach_type(&ty, basety);

        if (level == GLOBAL && params) {
            if (first_funcdef(ty)) {
                vec_push(v, funcdef(id, ty, sclass, fspec));
                return v;
            } else {
                exit_params();
            }
        }

        for (;;) {
            if (id) {
                int kind;
                if (dcl == globaldecl)
                    kind = GLOBAL;
                else if (dcl == paramdecl)
                    kind = PARAM;
                else
                    kind = LOCAL;
                node_t *decl = make_decl(id, ty, sclass, fspec, dcl);
                if (token->id == '=')
                    decl_initializer(decl, sclass, kind);
                ensure_decl(decl, sclass, kind);
                vec_push(v, decl);
            }

            if (token->id != ',')
                break;

            expect(',');
            id = NULL;
            ty = NULL;
            // declarator
            declarator(&ty, &id, NULL);
            attach_type(&ty, basety);
        }
    } else if (isenum(basety) || isstruct(basety) || isunion(basety)) {
        // struct/union/enum
        int node_id;
        node_t *decl;
        if (isstruct(basety))
            node_id = STRUCT_DECL;
        else if (isunion(basety))
            node_id = UNION_DECL;
        else
            node_id = ENUM_DECL;

        decl = ast_decl(node_id);
        DECL_SYM(decl) = TYPE_TSYM(basety);
        vec_push(v, decl);
    } else {
        error("invalid token '%s' in declaration", token->name);
    }
    match(';', follow);

    return v;
}
Ejemplo n.º 6
0
struct attach *
attach_get(struct mail *m, char **ptr, size_t *len, const char *b, int *last)
{
	struct attach	*atr, *at;
	char		*name = NULL, *b2 = NULL;
	size_t		 bl, bl2;
	int		 last2;
	u_int		 n;

	bl = strlen(b);

	atr = xmalloc(sizeof *atr);
	memset(atr, 0, sizeof *atr);
	TAILQ_INIT(&atr->children);

	atr->data = *ptr - m->data;

	while (*ptr != NULL) {
		if (*len >= 13 && strncasecmp(*ptr, "content-type:", 13) == 0)
			break;
		line_next(m, ptr, len);
	}
	if (*ptr == NULL)
		goto error;

	atr->type = attach_type(m, *ptr, "name", &name);
	if (atr->type == NULL) {
		if (name != NULL)
			xfree(name);
		goto error;
	}
	atr->name = name;

	if (strncasecmp(atr->type, "multipart/", 10) != 0) {
		/* Skip the remaining headers. */
		while (*ptr != NULL && *len > 1)
			line_next(m, ptr, len);
		if (*ptr == NULL)
			goto error;

		atr->body = *ptr - m->data;
		for (;;) {
			line_next(m, ptr, len);
			if (*ptr == NULL)
				break;
			if (*len < 3 || (*ptr)[0] != '-' || (*ptr)[1] != '-')
				continue;

			if (*len - 5 == bl && strncmp(*ptr + 2, b, bl) == 0 &&
			    strncmp(*ptr + bl + 2, "--", 2) == 0) {
				*last = 1;
				break;
			}
			if (*len - 3 == bl && strncmp(*ptr + 2, b, bl) == 0)
				break;
		}
		if (*ptr == NULL)
			goto error;

		atr->size = *ptr - m->data - atr->data;
	} else {
		/* XXX avoid doing this twice. */
		xfree(atr->type);
		atr->type = attach_type(m, *ptr, "boundary", &b2);
		if (b2 == NULL)
			goto error;
		bl2 = strlen(b2);

		/* Find the first boundary. */
		while (*ptr != NULL) {
			if ((*ptr)[0] == '-' && (*ptr)[1] == '-') {
				if (*len - 3 == bl2 &&
				    strncmp(*ptr + 2, b2, bl2) == 0)
					break;
			}
			line_next(m, ptr, len);
		}
		if (ptr == NULL)
			goto error;

		/* Now iterate over the rest. */
		last2 = 0;
		n = 0;
		while (*ptr != NULL && !last2) {
			at = attach_get(m, ptr, len, b2, &last2);
			if (at == NULL)
				goto error;
			at->idx = n++;
			at->parent = atr;
			TAILQ_INSERT_TAIL(&atr->children, at, entry);
		}

		/* And skip on to the end of the multipart. */
		while (*ptr != NULL) {
			if ((*ptr)[0] == '-' && (*ptr)[1] == '-') {
				if (*len - 5 == bl2 &&
				    strncmp(*ptr + 2, b2, bl2) == 0)
					break;
			}
			line_next(m, ptr, len);
		}
		if (*ptr == NULL)
			goto error;
		line_next(m, ptr, len);

		xfree(b2);
	}

	return (atr);

error:
	if (b2 != NULL)
		xfree(b2);

	attach_free(atr);
	return (NULL);
}
Ejemplo n.º 7
0
struct attach *
attach_build(struct mail *m)
{
	struct attach	*atr = NULL, *at;
	char		*hdr, *ptr, *b = NULL, *type;
	size_t		 len, bl;
	int		 last;
	u_int		 n;

	hdr = find_header(m, "content-type", &len, 0);
	if (hdr == NULL)
		return (NULL);

	type = attach_type(m, hdr, "boundary", &b);
	if (type == NULL || b == NULL) {
		if (type != NULL)
			xfree(type);
		goto error;
	}
	if (strncasecmp(type, "multipart/", 10) != 0) {
		xfree(type);
		goto error;
	}
	bl = strlen(b);

	atr = xmalloc(sizeof *atr);
	memset(atr, 0, sizeof *atr);
	TAILQ_INIT(&atr->children);
	atr->type = type;

	/* Find the first boundary. */
	line_init(m, &ptr, &len);
	while (ptr != NULL) {
		if (ptr[0] == '-' && ptr[1] == '-') {
			if (len - 3 == bl && strncmp(ptr + 2, b, bl) == 0)
				break;
		}
		line_next(m, &ptr, &len);
	}
	if (ptr == NULL)
		goto error;

	/* Now iterate over the rest. */
	last = 0;
	n = 0;
	while (ptr != NULL && !last) {
		if (ptr[0] == '-' && ptr[1] == '-') {
			if (len - 5 == bl && strncmp(ptr + 2, b, bl) == 0)
				break;
		}

		at = attach_get(m, &ptr, &len, b, &last);
		if (at == NULL)
			goto error;
		at->idx = n++;
		at->parent = atr;
		TAILQ_INSERT_TAIL(&atr->children, at, entry);
	}
	if (ptr == NULL)
		goto error;

	xfree(b);
	return (atr);

error:
	if (atr != NULL)
		attach_free(atr);

	if (b != NULL)
		xfree(b);
	return (NULL);
}