aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/sc_interp.c242
1 files changed, 135 insertions, 107 deletions
diff --git a/src/sc_interp.c b/src/sc_interp.c
index 15441ab..5f025c0 100644
--- a/src/sc_interp.c
+++ b/src/sc_interp.c
@@ -292,88 +292,85 @@ static LengthUnits get_units(const char *t)
}
-static void parse_frame_option(struct frame *fr, struct frame *parent,
- const char *opt)
+static int parse_dims(const char *opt, struct frame *parent,
+ double *wp, double *hp, double *xp, double *yp)
{
- if ( (index(opt, 'x') != NULL) && (index(opt, '+') != NULL)
- && (index(opt, '+') != rindex(opt, '+')) )
- {
- char *w;
- char *h;
- char *x;
- char *y;
- char *check;
- LengthUnits h_units, w_units;
-
- /* Looks like a dimension/position thing */
- w = strdup(opt);
- h = index(w, 'x');
- h[0] = '\0'; h++;
-
- x = index(h, '+');
- if ( x == NULL ) {
- fprintf(stderr, "Invalid option '%s'\n", opt);
- return;
- }
- x[0] = '\0'; x++;
+ char *w;
+ char *h;
+ char *x;
+ char *y;
+ char *check;
+ LengthUnits h_units, w_units;
- y = index(x, '+');
- if ( x == NULL ) {
- fprintf(stderr, "Invalid option '%s'\n", opt);
- return;
- }
- y[0] = '\0'; y++;
+ /* Looks like a dimension/position thing */
+ w = strdup(opt);
+ h = index(w, 'x');
+ h[0] = '\0'; h++;
- fr->w = strtod(w, &check);
- if ( check == w ) {
- fprintf(stderr, "Invalid option '%s'\n", opt);
- return;
- }
- w_units = get_units(w);
- if ( w_units == UNITS_FRAC ) {
- double pw = parent->w;
- pw -= parent->pad_l;
- pw -= parent->pad_r;
- fr->w = pw * fr->w;
- }
+ x = index(h, '+');
+ if ( x == NULL ) goto invalid;
+ x[0] = '\0'; x++;
- fr->h = strtod(h, &check);
- if ( check == h ) {
- fprintf(stderr, "Invalid option '%s'\n", opt);
- return;
- }
- h_units = get_units(h);
- if ( h_units == UNITS_FRAC ) {
- double ph = parent->h;
- ph -= parent->pad_t;
- ph -= parent->pad_b;
- fr->h = ph * fr->h;
- }
+ y = index(x, '+');
+ if ( x == NULL ) goto invalid;
+ y[0] = '\0'; y++;
+
+ *wp = strtod(w, &check);
+ if ( check == w ) goto invalid;
+ w_units = get_units(w);
+ if ( w_units == UNITS_FRAC ) {
+ double pw = parent->w;
+ pw -= parent->pad_l;
+ pw -= parent->pad_r;
+ *wp = pw * *wp;
+ }
- fr->x = strtod(x, &check);
- if ( check == x ) {
- fprintf(stderr, "Invalid option '%s'\n", opt);
- return;
- }
- fr->y = strtod(y, &check);
- if ( check == y ) {
- fprintf(stderr, "Invalid option '%s'\n", opt);
- return;
- }
+ *hp = strtod(h, &check);
+ if ( check == h ) goto invalid;
+ h_units = get_units(h);
+ if ( h_units == UNITS_FRAC ) {
+ double ph = parent->h;
+ ph -= parent->pad_t;
+ ph -= parent->pad_b;
+ *hp = ph * *hp;
+ }
+
+ *xp= strtod(x, &check);
+ if ( check == x ) goto invalid;
+ *yp = strtod(y, &check);
+ if ( check == y ) goto invalid;
+
+ return 0;
+
+invalid:
+ fprintf(stderr, "Invalid dimensions '%s'\n", opt);
+ return 1;
+}
+
+static int parse_frame_option(const char *opt, struct frame *fr,
+ struct frame *parent)
+{
+ if ( (index(opt, 'x') != NULL) && (index(opt, '+') != NULL)
+ && (index(opt, '+') != rindex(opt, '+')) ) {
+ return parse_dims(opt, parent, &fr->w, &fr->h, &fr->x, &fr->y);
}
+
+ fprintf(stderr, "Unrecognised frame option '%s'\n", opt);
+
+ return 1;
}
-static void parse_frame_options(struct frame *fr, struct frame *parent,
- const char *opth)
+static int parse_frame_options(struct frame *fr, struct frame *parent,
+ const char *opth)
{
int i;
size_t len;
size_t start;
char *opt;
- if ( opth == NULL ) return;
+ if ( opth == NULL ) return 1;
opt = strdup(opth);
@@ -385,59 +382,92 @@ static void parse_frame_options(struct frame *fr, struct frame *parent,
/* FIXME: comma might be escaped or quoted */
if ( opt[i] == ',' ) {
opt[i] = '\0';
- parse_frame_option(fr, parent, opt+start);
+ if ( parse_frame_option(opt+start, fr, parent) ) {
+ return 1;
+ }
start = i+1;
}
}
if ( start != len ) {
- parse_frame_option(fr, parent, opt+start);
+ if ( parse_frame_option(opt+start, fr, parent) ) return 1;
}
free(opt);
+
+ return 0;
}
-static int get_size(const char *a, struct frame *fr, int *wp, int *hp)
+static int parse_image_option(const char *opt, struct frame *parent,
+ double *wp, double *hp, char **filenamep)
{
- char *x;
- char *ws;
- char *hs;
+ if ( (index(opt, 'x') != NULL) && (index(opt, '+') != NULL)
+ && (index(opt, '+') != rindex(opt, '+')) ) {
+ double dum;
+ return parse_dims(opt, parent, wp, hp, &dum, &dum);
+ }
- if ( a == NULL ) goto invalid;
+ if ( strncmp(opt, "filename=\"", 10) == 0 ) {
+ char *fn;
+ fn = strdup(opt+10);
+ if ( fn[strlen(fn)-1] != '\"' ) {
+ fprintf(stderr, "Unterminated filename?\n");
+ free(fn);
+ return 1;
+ }
+ fn[strlen(fn)-1] = '\0';
+ *filenamep = fn;
+ return 0;
+ }
- x = index(a, 'x');
- if ( x == NULL ) goto invalid;
+ fprintf(stderr, "Unrecognised image option '%s'\n", opt);
- if ( rindex(a, 'x') != x ) goto invalid;
+ return 1;
+}
- ws = strndup(a, x-a);
- hs = strdup(x+1);
- if ( strcmp(ws, "fit") == 0 ) {
- *wp = fr->w - (fr->pad_l+fr->pad_r);
- } else {
- *wp = strtoul(ws, NULL, 10);
+
+static int parse_image_options(const char *opth, struct frame *parent,
+ double *wp, double *hp, char **filenamep)
+{
+ int i;
+ size_t len;
+ size_t start;
+ char *opt;
+
+ if ( opth == NULL ) return 1;
+
+ opt = strdup(opth);
+
+ len = strlen(opt);
+ start = 0;
+
+ for ( i=0; i<len; i++ ) {
+
+ /* FIXME: comma might be escaped or quoted */
+ if ( opt[i] == ',' ) {
+ opt[i] = '\0';
+ if ( parse_image_option(opt+start, parent,
+ wp, hp, filenamep) ) return 1;
+ start = i+1;
+ }
+
}
- if ( strcmp(ws, "fit") == 0 ) {
- *hp = fr->h - (fr->pad_t+fr->pad_b);
- } else {
- *hp = strtoul(hs, NULL, 10);
+
+ if ( start != len ) {
+ if ( parse_image_option(opt+start, parent,
+ wp, hp, filenamep) ) return 1;
}
- free(ws);
- free(hs);
+ free(opt);
return 0;
-
-invalid:
- fprintf(stderr, "Invalid dimensions '%s'\n", a);
- return 1;
}
-static int check_outputs(SCBlock *bl, SCInterpreter *scin, int *recurse)
+static int check_outputs(SCBlock *bl, SCInterpreter *scin)
{
const char *name = sc_block_name(bl);
const char *options = sc_block_options(bl);
@@ -453,14 +483,17 @@ static int check_outputs(SCBlock *bl, SCInterpreter *scin, int *recurse)
set_frame_bgcolour(sc_interp_get_frame(scin), options);
} else if ( strcmp(name, "image")==0 ) {
- int w, h;
- if ( get_size(options, sc_interp_get_frame(scin),
- &w, &h) == 0 )
+ double w, h;
+ char *filename;
+ if ( parse_image_options(options, sc_interp_get_frame(scin),
+ &w, &h, &filename) == 0 )
{
add_image_box(sc_interp_get_frame(scin)->boxes,
- sc_block_contents(child),
- w, h, 1);
- *recurse = 0;
+ filename, w, h, 1);
+ free(filename);
+ } else {
+ fprintf(stderr, "Invalid image options '%s'\n",
+ options);
}
} else if ( strcmp(name, "slidenumber")==0) {
@@ -495,8 +528,7 @@ static int check_outputs(SCBlock *bl, SCInterpreter *scin, int *recurse)
parse_frame_options(fr, sc_interp_get_frame(scin),
options);
- sc_interp_set_frame(scin, fr);
- *recurse = 1;
+ set_frame(scin, fr);
} else {
return 0;
@@ -510,10 +542,8 @@ int sc_interp_add_blocks(SCInterpreter *scin, SCBlock *bl)
{
while ( bl != NULL ) {
- int recurse = 0;
const char *name = sc_block_name(bl);
const char *options = sc_block_options(bl);
- const char *contents = sc_block_contents(bl);
SCBlock *child = sc_block_child(bl);
if ( child != NULL ) {
@@ -521,7 +551,7 @@ int sc_interp_add_blocks(SCInterpreter *scin, SCBlock *bl)
}
if ( (sc_interp_get_frame(scin) != NULL)
- && check_outputs(bl, scin, &recurse) ) {
+ && check_outputs(bl, scin) ) {
/* Block handled as output thing */
} else if ( name == NULL ) {
@@ -529,11 +559,9 @@ int sc_interp_add_blocks(SCInterpreter *scin, SCBlock *bl)
} else if ( strcmp(name, "font") == 0 ) {
set_font(scin, options);
- recurse = 1;
} else if ( strcmp(name, "fgcol") == 0 ) {
set_colour(scin, options);
- recurse = 1;
} else {
@@ -543,7 +571,7 @@ int sc_interp_add_blocks(SCInterpreter *scin, SCBlock *bl)
}
if ( child != NULL ) {
- if ( recurse ) sc_interp_add_blocks(scin, child);
+ sc_interp_add_blocks(scin, child);
sc_interp_restore(scin);
}
bl = sc_block_next(bl);