#include #include #include #include "stylesheet.h" SSTerm * term_new(SSTermType type) { SSTerm *p; if ((p = malloc(sizeof(*p))) == NULL) { perror("term_new"); exit(1); } p->type = type; p->str = NULL; return p; } void term_delete(SSTerm *p) { if (p) { if (p->str) free(p->str); free(p); } } void term_show(SSTerm *p) { switch (p->type) { case SSTERM_NUMBER: fprintf(stderr, "%f\n", p->num); break; case SSTERM_PERCENTAGE: fprintf(stderr, "%f%%\n", p->num); break; case SSTERM_LENGTH_PT: fprintf(stderr, "%fpt\n", p->num); break; case SSTERM_LENGTH_MM: fprintf(stderr, "%fmm\n", p->num); break; case SSTERM_LENGTH_CM: fprintf(stderr, "%fcm\n", p->num); break; case SSTERM_LENGTH_PC: fprintf(stderr, "%fpc\n", p->num); break; case SSTERM_LENGTH_IN: fprintf(stderr, "%fin\n", p->num); break; case SSTERM_LENGTH_PX: fprintf(stderr, "%fpx\n", p->num); break; case SSTERM_EMS: fprintf(stderr, "%fem\n", p->num); break; case SSTERM_EXS: fprintf(stderr, "%fex\n", p->num); break; case SSTERM_IDENT: fprintf(stderr, "%s\n", SSIDToString(p->id)); break; case SSTERM_STRING: case SSTERM_HEXCOLOR: case SSTERM_URL: case SSTERM_RGB: fprintf(stderr, "%s\n", p->str); } } SSDeclaration * declaration_new(SSID ident, SSTerm *term, int pr) { SSDeclaration *p; if ((p = malloc(sizeof(*p))) == NULL) { perror("declaration_new"); exit(1); } p->ident = ident; p->term = term; p->priority = pr; p->ref = 1; #ifdef DEBUG declaration_show(p); #endif return p; } void declaration_delete(SSDeclaration *p) { if (p) { if (--p->ref <= 0) { term_delete(p->term); free(p); } } } void declaration_show(SSDeclaration *p) { if (p->ident != None) { fprintf(stderr, "%s:", SSIDToString(p->ident)); term_show(p->term); } else fprintf(stderr, "none:\n"); } SSDeclarationSet * declarationset_new(SSDeclaration *d) { SSDeclarationSet *p; if ((p = malloc(sizeof(*p))) == NULL) { perror("declaration_new"); exit(1); } p->next = NULL; p->decl = d; d->ref++; return p; } void declarationset_delete(SSDeclarationSet *p) { if (p) { declaration_delete(p->decl); free(p); } } void declarationsetlist_delete(SSDeclarationSetList l) { SSDeclarationSet *p = l, *q; while (p != NULL) { q = p; p = p->next; declarationset_delete(q); } } void declarationsetlist_show(SSDeclarationSetList l) { SSDeclarationSet *p = l; while (p != NULL) { declaration_show(p->decl); p = p->next; } } SSSimpleSelector * simpleselector_new(SSID ident, SSID id, SSID class, int pc) { SSSimpleSelector *p; if ((p = malloc(sizeof(*p))) == NULL) { perror("simpleselector_new"); exit(1); } p->next = NULL; p->ident = ident; p->id = id; p->class = class; p->pseudoclass = pc; return p; } void simpleselector_delete(SSSimpleSelector *p) { if (p) { free(p); } } void simpleselectorlist_delete(SSSimpleSelectorList l) { SSSimpleSelector *p = l, *q; while (p != NULL) { q = p; p = p->next; simpleselector_delete(q); } } void simpleselector_show(SSSimpleSelector *p) { if (p->ident != None) fprintf(stderr, SSIDToString(p->ident)); if (p->id != None) fprintf(stderr, "#%s", SSIDToString(p->id)); if (p->class != None) fprintf(stderr, ".%s", SSIDToString(p->class)); if (p->pseudoclass != 0) fprintf(stderr, "[%d]", p->pseudoclass); fprintf(stderr, " "); } void simpleselectorlist_show(SSSimpleSelectorList l) { SSSimpleSelector *p = l; while (p != NULL) { simpleselector_show(p); p = p->next; } } SSSelector * selector_new(SSSimpleSelectorList sl, int pe) { SSSelector *p; SSSimpleSelector *s = sl; int spec; if ((p = malloc(sizeof(*p))) == NULL) { perror("selector_new"); exit(1); } p->selectors = sl; p->pseudoelement = pe; spec = 0; while (s != NULL) { spec += ((s->ident)?1:0) + ((s->class)?100:0) + ((s->id)?10000:0) +((s->pseudoclass)?100:0); s = s->next; } p->specificity = spec; #ifdef DEBUG selector_show(p); #endif return p; } void selector_delete(SSSelector *p) { if (p) { if (p->selectors) simpleselectorlist_delete(p->selectors); free(p); } } void selector_show(SSSelector *p) { simpleselectorlist_show(p->selectors); if (p->pseudoelement) fprintf(stderr, "pe[%d] ", p->pseudoelement); fprintf(stderr, "spec[%d] ", p->specificity); } SSSelectorSet * selectorset_new(SSSelector *s) { SSSelectorSet *p; if ((p = malloc(sizeof(*p))) == NULL) { perror("selector_new"); exit(1); } p->next = NULL; p->sel = s; return p; } void selectorset_delete(SSSelectorSet *p) { if (p) { selector_delete(p->sel); free(p); } } void selectorsetlist_delete(SSSelectorSetList l) { SSSelectorSet *p = l, *q; while (p != NULL) { q = p; p = p->next; selectorset_delete(q); } } StyleSheet * stylesheet_new(void) { StyleSheet *p; if ((p = malloc(sizeof(*p))) == NULL) { perror("stylesheet_new"); exit(1); } p->next = NULL; p->sel = NULL; p->decls = NULL; return p; } void stylesheet_delete(StyleSheet *p) { if (p) { selector_delete(p->sel); declarationsetlist_delete(p->decls); free(p); } } void stylesheet_show(StyleSheet *p) { selector_show(p->sel); fprintf(stderr, "\n"); declarationsetlist_show(p->decls); fprintf(stderr, "\n"); } void stylesheetlist_show(StyleSheetList l) { StyleSheet *p = l; while (p != NULL) { stylesheet_show(p); p = p->next; } } void stylesheetlist_delete(StyleSheetList l) { StyleSheet *p = l, *q; while (p != NULL) { q = p; p = p->next; stylesheet_delete(q); } } int simpleselector_eq(SSSimpleSelector *s1, SSSimpleSelector *s2) { if (s1->ident == s2->ident && s1->id == s2->id && s1->class == s1->class && s1->pseudoclass == s2->pseudoclass) return 1; return 0; } int selector_eq(SSSelector *s1, SSSelector *s2) { SSSimpleSelector *ss1 = s1->selectors; SSSimpleSelector *ss2 = s2->selectors; if (s1->pseudoelement != s2->pseudoelement) return 0; while (ss1 != NULL && ss2 != NULL) { if (!simpleselector_eq(ss1, ss2)) return 0; ss1=ss1->next; ss2=ss2->next; } if (ss1 == NULL && ss2 == NULL) return 1; else return 0; } StyleSheet * stylesheet_find(StyleSheetList base, SSSelector *sel) { StyleSheet *p = base; while (p != NULL) { if (selector_eq(p->sel, sel)) return p; p = p->next; } return NULL; } extern StyleSheetList base_sheet; void stylesheet_add(SSSelectorSetList sl, SSDeclarationSetList dsl) { SSSelectorSet *p = sl; StyleSheet *ss; SSDeclarationSet *dsp, *dsp2; while (p != NULL) { if (!(ss = stylesheet_find(base_sheet, p->sel))) { /* new selector */ ss = stylesheet_new(); ss->sel = p->sel; /* move */ p->sel = NULL; ss->next = base_sheet; /* insert */ base_sheet = ss; } dsp = dsl; while (dsp != NULL) { /* add decl */ dsp2 = declarationset_new(dsp->decl); dsp2->next = ss->decls; ss->decls = dsp2; dsp = dsp->next; } p = p->next; } selectorsetlist_delete(sl); declarationsetlist_delete(dsl); } SSID StringToSSID(char *str) { SSID ret; char *h, *p, *s; if ((h = p = malloc(strlen(s = str)+1)) == NULL) { perror("malloc"); exit(1); } while (*s) *p++ = tolower(*s++); *p = '\0'; ret = XrmStringToQuark(h); free(h); return ret; }