Пример #1
0
/* merge style sheet 'a' in 's' */
void css_merge_style_sheet(CSSStyleSheet *s, CSSStyleSheet *a)
{
    CSSStyleSheetEntry *e, *e1;
    CSSSimpleSelector *ss, *ss1, ss2, **pss;

    for (e = a->first_entry; e != NULL; e = e->next) {
        /* add selector */
        dup_selector(&ss2, &e->sel);
        e1 = add_style_entry(s, &ss2, e->media);

        /* add selector operations */
        pss = &e1->sel.next;
        for (ss = e->sel.next; ss != NULL; ss = ss->next) {
            ss1 = malloc(sizeof(CSSSimpleSelector));
            dup_selector(ss1, ss);
            *pss = ss1;
            pss = &ss1->next;
        }

        /* add css properties */
        e1->props = dup_properties(e->props);
    }
}
Пример #2
0
/* flags: only XML_IGNORE_CASE is handled */
void css_parse_style_sheet(CSSStyleSheet *s, CSSParseState *b)
{
    char value[1024];
    char tag[64];
    char tag_id[64];
    char *q;
    int ch, media, val, last_tree_op, i;
    CSSStyleSheetEntry *e, **first_eprops;
    CSSSimpleSelector ss2, *ss = &ss2, *last_ss, *ss1;
    CSSProperty *props;

    ch = bgetc(b);
    media = CSS_MEDIA_ALL;
    for (;;) {
redo:
        first_eprops = s->plast_entry;
        bskip_spaces(b, &ch);
        if (ch == EOF)
            break;
        /* eat inserted HTML comments for compatible STYLE tag parsing */
        if (ch == '<') {
            beat(b, &ch, "<!--");
            goto redo;
        } else if (ch == '-') {
            beat(b, &ch, "-->");
            goto redo;
        }

        /* handle '@media { ... }' */
        if (ch == '@') {
            ch = bgetc(b);
            read_ident(b, &ch, tag, sizeof(tag));
            switch (css_get_enum(tag, "media,page")) {
            case 0:
                /* @media */
                media = 0;
                for (;;) {
                    bskip_spaces(b, &ch);
                    read_ident(b, &ch, tag, sizeof(tag));
                    val = css_get_enum(tag, "tty,screen,print,tv,speech,all");
                    if (val < 0 || val == 5)
                        media = CSS_MEDIA_ALL;
                    else
                        media |= (1 << val);
                    bskip_spaces(b, &ch);
                    if (ch == ',') {
                        ch = bgetc(b);
                    } else if (ch == '{' || ch == EOF) {
                        ch = bgetc(b);
                        break;
                    }
                }
                goto redo;
            case 1:
                /* @page */
                bskip_spaces(b, &ch);
                if (ch != '{') {
                    read_ident(b, &ch, tag_id, sizeof(tag_id));
                    bskip_spaces(b, &ch);
                }
                memset(ss, 0, sizeof(CSSSimpleSelector));
                ss->tag = css_new_ident("@page");
                if (tag_id[0] != '\0')
                    ss->tag_id = css_new_ident(tag_id);
                add_style_entry(s, ss, media);
                goto parse_props;
            default:
                css_error1(b, "unrecognized css directive '@%s'", tag);
                break;
            }
        } else if (ch == '}') {
            /* XXX: end of media, should unstack */
            ch = bgetc(b);
            goto redo;
        }

        /* parse a selector list */
        for (;;) {
            /* parse simple selectors with operations */
            last_ss = NULL;
            last_tree_op = CSS_TREE_OP_NONE;
            for (;;) {
                int tree_op;
                bskip_spaces(b, &ch);
                parse_simple_selector(ss, b, &ch);
                bskip_spaces(b, &ch);
                ss->tree_op = last_tree_op;
                ss->next = last_ss;
                if (ch == '+') {
                    tree_op = CSS_TREE_OP_PRECEEDED;
                    ch = bgetc(b);
                    goto add_tree;
                } else if (ch == '>') {
                    tree_op = CSS_TREE_OP_CHILD;
                    ch = bgetc(b);
                    goto add_tree;
                } else if (isalpha(ch)) {
                    tree_op = CSS_TREE_OP_DESCENDANT;
add_tree:
                    ss1 = malloc(sizeof(CSSSimpleSelector));
                    if (ss1) {
                        memcpy(ss1, ss, sizeof(CSSSimpleSelector));
                        last_ss = ss1;
                    }
                    last_tree_op = tree_op;
                } else {
                    /* other char: exit */
                    break;
                }
            }
            add_style_entry(s, ss, media);

            /* get next selector, if present */
            if (ch != ',')
                break;
            ch = bgetc(b);
        }
parse_props:
        /* expect start of properties */
        if (ch != '{')
            break;
        ch = bgetc(b);

        q = value;
        while (ch != '}' && ch != EOF) {
            if ((q - value) < (int)sizeof(value) - 1)
                *q++ = ch;
            ch = bgetc(b);
        }
        *q = '\0';

        if (ch == '}')
            ch = bgetc(b);

        /* the properties are extracted, now add them to each tag */
        /* XXX: should locate entries first, then add, to avoid adding
           duplicate entries */
        /* XXX: should put font properties first to avoid em/ex units
           problems, but it would still not be sufficient. */
        props = css_parse_properties(b, value);
        i = 0;
        for (e = *first_eprops; e != NULL; e = e->next) {
            if (i == 0)
                e->props = props;
            else
                e->props = dup_properties(props);
            i++;
        }
    }
#ifdef DEBUG
    css_dump_style_sheet(s);
#endif
}
Пример #3
0
/* returns added device node so it can be added to procfs in the case
 * of hotpluging */
static struct device_node *xen_add_vcpu_node(struct device_node *boot_cpu,
					     uint cpu)
{
	struct device_node *new_cpu;
	struct property *pp;
	void *p;
	int sz;
	int type_sz;
	int name_sz;

	DBG("%s: boot cpu: %s\n", __func__, boot_cpu->full_name);

	/* allocate in one shot in case we fail */
	name_sz = strlen(boot_cpu->name) + 1;
	type_sz = strlen(boot_cpu->type) + 1;

	sz = sizeof (*new_cpu);	/* the node */
	sz += strlen(boot_cpu->full_name) + 3; /* full_name */
	sz += name_sz; /* name */
	sz += type_sz; /* type */

	p = xen_of_alloc(sz);
	if (!p)
		return NULL;
	memset(p, 0, sz);

	/* the node */
	new_cpu = p;
	p += sizeof (*new_cpu);
	
	/* name */
	new_cpu->name = p;
	strcpy(new_cpu->name, boot_cpu->name);
	p += name_sz;
	
	/* type */
	new_cpu->type = p;
	strcpy(new_cpu->type, boot_cpu->type);
	p += type_sz;

	/* full_name */
	new_cpu->full_name = p;

	/* assemble new full_name */
	pp = of_find_property(boot_cpu, "name", NULL);
	if (!pp)
		panic("%s: no name prop\n", __func__);

	DBG("%s: name is: %s = %s\n", __func__, pp->name, pp->value);
	sprintf(new_cpu->full_name, "/cpus/%s@%u", pp->value, cpu);

	if (dup_properties(new_cpu, boot_cpu)) {
		xen_of_free(new_cpu);
		return NULL;
	}

	/* fixup reg property */
	DBG("%s: updating reg: %d\n", __func__, cpu);
	pp = of_find_property(new_cpu, "reg", NULL);
	if (!pp)
		panic("%s: no reg prop\n", __func__);
	*(int *)pp->value = cpu;

	if (mem_init_done)
		OF_MARK_DYNAMIC(new_cpu);

	kref_init(&new_cpu->kref);

	/* insert the node */
	new_cpu->parent = of_get_parent(boot_cpu);
	of_attach_node(new_cpu);
	of_node_put(new_cpu->parent);

	return new_cpu;
}