| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
#ifndef LITAVIS_H |
|
2
|
|
|
|
|
|
|
#define LITAVIS_H |
|
3
|
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
/* |
|
5
|
|
|
|
|
|
|
* litavis.h - Perl XS wrapper for the Litavis CSS preprocessor |
|
6
|
|
|
|
|
|
|
* |
|
7
|
|
|
|
|
|
|
* This header sets up Perl-specific error handling, includes the |
|
8
|
|
|
|
|
|
|
* pure C engine headers, and defines the top-level context struct. |
|
9
|
|
|
|
|
|
|
* |
|
10
|
|
|
|
|
|
|
* For reuse from OTHER XS modules, include the individual headers |
|
11
|
|
|
|
|
|
|
* directly (litavis_ast.h, etc.) instead. |
|
12
|
|
|
|
|
|
|
*/ |
|
13
|
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
#define PERL_NO_GET_CONTEXT |
|
15
|
|
|
|
|
|
|
#include "EXTERN.h" |
|
16
|
|
|
|
|
|
|
#include "perl.h" |
|
17
|
|
|
|
|
|
|
#include "XSUB.h" |
|
18
|
|
|
|
|
|
|
#include "ppport.h" |
|
19
|
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
/* Route fatal errors through Perl's croak() */ |
|
21
|
|
|
|
|
|
|
#define LITAVIS_FATAL(msg) croak("litavis: %s", (msg)) |
|
22
|
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
/* Pull in the C engine — order-independent headers first */ |
|
24
|
|
|
|
|
|
|
#include "litavis_ast.h" |
|
25
|
|
|
|
|
|
|
#include "litavis_tokeniser.h" |
|
26
|
|
|
|
|
|
|
#include "litavis_cascade.h" |
|
27
|
|
|
|
|
|
|
#include "litavis_vars.h" |
|
28
|
|
|
|
|
|
|
#include "litavis_colour.h" |
|
29
|
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
#define LITAVIS_VERSION "0.01" |
|
31
|
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
/* ── Top-level context — holds all state for one Litavis instance ── */ |
|
33
|
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
typedef struct { |
|
35
|
|
|
|
|
|
|
LitavisAST *ast; /* accumulated parsed rules */ |
|
36
|
|
|
|
|
|
|
LitavisVarScope *global_scope; /* preprocessor variable scope */ |
|
37
|
|
|
|
|
|
|
LitavisMixinStore *mixins; /* mixin definitions */ |
|
38
|
|
|
|
|
|
|
LitavisMapStore *maps; /* map variable definitions */ |
|
39
|
|
|
|
|
|
|
int pretty; /* 0 = minified, 1 = pretty */ |
|
40
|
|
|
|
|
|
|
int dedupe; /* 0 = off, 1 = conservative, 2 = aggressive */ |
|
41
|
|
|
|
|
|
|
char *indent; /* indent string for pretty mode */ |
|
42
|
|
|
|
|
|
|
int shorthand_hex; /* 1 = #fff, 0 = #ffffff */ |
|
43
|
|
|
|
|
|
|
int sort_props; /* 1 = alphabetise properties */ |
|
44
|
|
|
|
|
|
|
} LitavisCtx; |
|
45
|
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
/* Headers that depend on LitavisCtx */ |
|
47
|
|
|
|
|
|
|
#include "litavis_parser.h" |
|
48
|
|
|
|
|
|
|
#include "litavis_emitter.h" |
|
49
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
/* ── Context lifecycle ────────────────────────────────────────── */ |
|
51
|
|
|
|
|
|
|
|
|
52
|
312
|
|
|
|
|
|
static LitavisCtx* litavis_ctx_new(void) { |
|
53
|
312
|
|
|
|
|
|
LitavisCtx *ctx = (LitavisCtx*)malloc(sizeof(LitavisCtx)); |
|
54
|
312
|
50
|
|
|
|
|
if (!ctx) LITAVIS_FATAL("out of memory"); |
|
55
|
312
|
|
|
|
|
|
ctx->ast = litavis_ast_new(16); |
|
56
|
312
|
|
|
|
|
|
ctx->global_scope = litavis_scope_new(NULL); |
|
57
|
312
|
|
|
|
|
|
ctx->mixins = litavis_mixin_store_new(); |
|
58
|
312
|
|
|
|
|
|
ctx->maps = litavis_map_store_new(); |
|
59
|
312
|
|
|
|
|
|
ctx->pretty = 0; |
|
60
|
312
|
|
|
|
|
|
ctx->dedupe = 1; /* conservative by default */ |
|
61
|
312
|
|
|
|
|
|
ctx->indent = litavis_strdup(" "); |
|
62
|
312
|
|
|
|
|
|
ctx->shorthand_hex = 1; |
|
63
|
312
|
|
|
|
|
|
ctx->sort_props = 0; |
|
64
|
312
|
|
|
|
|
|
return ctx; |
|
65
|
|
|
|
|
|
|
} |
|
66
|
|
|
|
|
|
|
|
|
67
|
312
|
|
|
|
|
|
static void litavis_ctx_free(LitavisCtx *ctx) { |
|
68
|
312
|
50
|
|
|
|
|
if (!ctx) return; |
|
69
|
312
|
50
|
|
|
|
|
if (ctx->ast) litavis_ast_free(ctx->ast); |
|
70
|
312
|
50
|
|
|
|
|
if (ctx->global_scope) litavis_scope_free(ctx->global_scope); |
|
71
|
312
|
50
|
|
|
|
|
if (ctx->mixins) litavis_mixin_store_free(ctx->mixins); |
|
72
|
312
|
50
|
|
|
|
|
if (ctx->maps) litavis_map_store_free(ctx->maps); |
|
73
|
312
|
50
|
|
|
|
|
if (ctx->indent) free(ctx->indent); |
|
74
|
312
|
|
|
|
|
|
free(ctx); |
|
75
|
|
|
|
|
|
|
} |
|
76
|
|
|
|
|
|
|
|
|
77
|
9
|
|
|
|
|
|
static void litavis_ctx_reset(LitavisCtx *ctx) { |
|
78
|
9
|
50
|
|
|
|
|
if (!ctx) return; |
|
79
|
9
|
50
|
|
|
|
|
if (ctx->ast) litavis_ast_free(ctx->ast); |
|
80
|
9
|
|
|
|
|
|
ctx->ast = litavis_ast_new(16); |
|
81
|
9
|
50
|
|
|
|
|
if (ctx->global_scope) litavis_scope_free(ctx->global_scope); |
|
82
|
9
|
|
|
|
|
|
ctx->global_scope = litavis_scope_new(NULL); |
|
83
|
9
|
50
|
|
|
|
|
if (ctx->mixins) litavis_mixin_store_free(ctx->mixins); |
|
84
|
9
|
|
|
|
|
|
ctx->mixins = litavis_mixin_store_new(); |
|
85
|
9
|
50
|
|
|
|
|
if (ctx->maps) litavis_map_store_free(ctx->maps); |
|
86
|
9
|
|
|
|
|
|
ctx->maps = litavis_map_store_new(); |
|
87
|
|
|
|
|
|
|
} |
|
88
|
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
#endif /* LITAVIS_H */ |