Skip to content

Commit 3de7866

Browse files
committed
fix #include
- relative to enclosing file - close on pop
1 parent b9fe3e8 commit 3de7866

6 files changed

Lines changed: 70 additions & 37 deletions

File tree

TODO

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,3 @@
1-
- better #include file resolving
2-
3-
should be relative to enclosing file, if any
4-
5-
6-
7-
81
- add something to open a dcraw image in 16 bits
92

103
- text widget should have an rgba toggle

src/lex.l

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ FALSE {
274274
BEGIN BINARY;
275275

276276
if (sscanf(yytext, "0x%x", &i ) != 1)
277-
nip2yyerror(_( "bad number %s"), yytext);
277+
nipyyerror(_( "bad number %s"), yytext);
278278

279279
yylval.yy_const.type = PARSE_CONST_NUM;
280280
yylval.yy_const.val.num = i;
@@ -354,5 +354,5 @@ FALSE {
354354
[ \t\n\r\m\01] ;
355355

356356
. {
357-
nip2yyerror(_( "illegal character \"%c\"" ), *yytext);
357+
nipyyerror(_( "illegal character \"%c\"" ), *yytext);
358358
}

src/model.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,7 @@ model_loadstate_rewrite(ModelLoadState *state, char *old_rhs, char *new_rhs)
309309
/* Here for yyerror in lex. Just ignore errors --- the parser
310310
* will spot them later anyway.
311311
*/
312+
reset_input_state();
312313
model_loadstate = NULL;
313314
return;
314315
}

src/parse.y

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -261,14 +261,28 @@ directive:
261261
if ($2.type != PARSE_CONST_STR)
262262
yyerror(_("not string argument"));
263263

264-
iOpenFile *of = ifile_open_read("%s", $2.val.str);
264+
iOpenFile *of;
265+
266+
/* Local paths are resolved relative to the enclosing file, if any.
267+
*/
268+
InputState *is = get_input_state();
269+
if (!is_absolute($2.val.str) &&
270+
is->of &&
271+
is->of->fname) {
272+
g_autofree char *dirname = g_path_get_dirname(is->of->fname);
273+
of = ifile_open_read("%s/%s", dirname, $2.val.str);
274+
}
275+
else
276+
of = ifile_open_read("%s", $2.val.str);
277+
265278
if (!of)
266279
yyerror(_("no such file"));
267280

268281
push_input_state();
269282
attach_input_file(of);
270283

271-
// gets popped and freed on EOF
284+
// close on pop
285+
is->close = of;
272286
}
273287
;
274288

@@ -1023,7 +1037,7 @@ VipsBuf lex_text = VIPS_BUF_STATIC(lex_text_buffer);
10231037

10241038
/* State of input system.
10251039
*/
1026-
InputState input_state[MAX_INCLUDE];
1040+
InputState input_state[MAX_INCLUDE] = { 0 };
10271041
int input_state_p = 0;
10281042

10291043
/* Defintions for the static decls at the top. We have to put the defs down
@@ -1048,10 +1062,10 @@ int parse_object_id = 0;
10481062
/* Here for errors in parse.
10491063
*
10501064
* Bison calls yyerror with only a char* arg. This printf() version is called
1051-
* from nip2 in a few places during parse.
1065+
* in a few places during parse.
10521066
*/
10531067
void
1054-
nip2yyerror(const char *sub, ...)
1068+
nipyyerror(const char *sub, ...)
10551069
{
10561070
va_list ap;
10571071
char buf[4096];
@@ -1077,7 +1091,7 @@ nip2yyerror(const char *sub, ...)
10771091
void
10781092
yyerror(const char *msg)
10791093
{
1080-
nip2yyerror("%s", msg);
1094+
nipyyerror("%s", msg);
10811095
}
10821096

10831097
InputState *
@@ -1087,7 +1101,7 @@ get_input_state(void)
10871101
}
10881102

10891103
void
1090-
push_input_state()
1104+
push_input_state(void)
10911105
{
10921106
if (input_state_p >= MAX_INCLUDE)
10931107
yyerror(_("too many nested includes"));
@@ -1096,14 +1110,30 @@ push_input_state()
10961110
}
10971111

10981112
void
1099-
pop_input_state()
1113+
pop_input_state(void)
11001114
{
11011115
if (input_state_p <= 0)
11021116
yyerror(_("too many pops!"));
11031117
else
11041118
input_state_p -= 1;
11051119
}
11061120

1121+
void
1122+
free_input_state(void)
1123+
{
1124+
InputState *is = get_input_state();
1125+
VIPS_FREEF(ifile_close, is->close);
1126+
}
1127+
1128+
void
1129+
reset_input_state(void)
1130+
{
1131+
while (input_state_p > 0) {
1132+
free_input_state();
1133+
pop_input_state();
1134+
}
1135+
}
1136+
11071137
/* Attach yyinput to a file.
11081138
*/
11091139
void
@@ -1244,6 +1274,7 @@ ip_input(void)
12441274
if (ch == 0) {
12451275
if (input_state_p > 0) {
12461276
// this input_state is at EOF, step out one level and try again
1277+
free_input_state();
12471278
pop_input_state();
12481279

12491280
return ip_input();
@@ -1572,6 +1603,8 @@ parse_input(int ch, Symbol *sym, Toolkit *kit, int pos)
15721603
ip_unput(ch);
15731604

15741605
if (setjmp(parse_error_point)) {
1606+
reset_input_state();
1607+
15751608
/* Restore current_compile.
15761609
*/
15771610
scope_pop_all();
@@ -1697,6 +1730,7 @@ parse_test_define(void)
16971730
if (setjmp(parse_error_point)) {
16981731
/* Here for yyerror in lex.
16991732
*/
1733+
reset_input_state();
17001734
VIPS_FREE(ident);
17011735

17021736
return NULL;
@@ -1736,6 +1770,7 @@ parse_set_symbol(void)
17361770
if (setjmp(parse_error_point)) {
17371771
/* Here for yyerror in lex.
17381772
*/
1773+
reset_input_state();
17391774
VIPS_FREE(ident);
17401775
return NULL;
17411776
}
@@ -1753,11 +1788,11 @@ parse_set_symbol(void)
17531788
* come. Look up this one and move to that context.
17541789
*/
17551790
if (!(sym = compile_lookup(compile, ident)))
1756-
nip2yyerror(_("'%s' does not exist"),
1791+
nipyyerror(_("'%s' does not exist"),
17571792
ident);
17581793
if (!sym->expr ||
17591794
!sym->expr->compile)
1760-
nip2yyerror(_("'%s' has no members"),
1795+
nipyyerror(_("'%s' has no members"),
17611796
ident);
17621797
compile = sym->expr->compile;
17631798
VIPS_FREE(ident);

src/parser.h

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -31,36 +31,40 @@
3131
* Keep track of the state of play here.
3232
*/
3333
typedef struct {
34-
iOpenFile *of; /* Non-NULL if we read from a file */
35-
char *str; /* Non-NULL if we read from a string */
36-
char *strpos; /* Position in string */
34+
iOpenFile *of; /* Non-NULL if we read from a file */
35+
char *str; /* Non-NULL if we read from a string */
36+
char *strpos; /* Position in string */
3737

38-
char buf[MAX_STRSIZE]; /* Accumulate text of each definition here */
39-
int bwp; /* Write point in the above */
40-
int bsp[MAX_SSTACK]; /* Start point stack */
41-
int bspsp; /* Stack pointer */
38+
char buf[MAX_STRSIZE]; /* Accumulate text of each definition here */
39+
int bwp; /* Write point in the above */
40+
int bsp[MAX_SSTACK]; /* Start point stack */
41+
int bspsp; /* Stack pointer */
4242

43-
int lineno; /* Current line number */
44-
int charno; /* Character in line */
45-
int pcharno; /* Characters in previous line */
46-
int charpos; /* Characters read by lex so far */
43+
int lineno; /* Current line number */
44+
int charno; /* Character in line */
45+
int pcharno; /* Characters in previous line */
46+
int charpos; /* Characters read by lex so far */
4747

48-
int oldchar; /* unget buffer, -1 for no unget */
48+
int oldchar; /* unget buffer, -1 for no unget */
49+
50+
iOpenFile *close; /* Close this iOpenFile on input_state close */
4951
} InputState;
5052

5153
#define MAX_INCLUDE (20)
5254
extern InputState input_state[MAX_INCLUDE];
5355
extern int input_state_p;
5456

55-
InputState *get_input_state();
56-
void pop_input_state();
57-
void push_input_state();
57+
InputState *get_input_state(void);
58+
void pop_input_state(void);
59+
void push_input_state(void);
60+
void free_input_state(void);
61+
void reset_input_state(void);
5862

5963
extern int parse_serial_number;
6064

6165
/* Function declarations for parse.y.
6266
*/
63-
void nip2yyerror(const char *sub, ...)
67+
void nipyyerror(const char *sub, ...)
6468
__attribute__((format(printf, 1, 2)));
6569
void yyerror(const char *msg);
6670
#ifdef YYLENG_IS_YY_SIZE_T

src/symbol.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -835,7 +835,7 @@ symbol_new_defining(Compile *compile, const char *name)
835835
/* Block definition of "root" anywhere ... too confusing.
836836
*/
837837
if (strcmp(name, IOBJECT(symbol_root)->name) == 0)
838-
nip2yyerror(_("Attempt to redefine root symbol \"%s\"."), name);
838+
nipyyerror(_("Attempt to redefine root symbol \"%s\"."), name);
839839

840840
/* Is this a redefinition of an existing symbol in this scope?
841841
*/
@@ -891,7 +891,7 @@ symbol_new_defining(Compile *compile, const char *name)
891891
}
892892
vips_buf_appendf(&buf, ".");
893893

894-
nip2yyerror("%s", vips_buf_all(&buf));
894+
nipyyerror("%s", vips_buf_all(&buf));
895895
/*NOTREACHED*/
896896
}
897897

0 commit comments

Comments
 (0)