/* 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); } }
/* 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 }
/* 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; }