@@ -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 } ;
10271041int 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 */
10531067void
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, ...)
10771091void
10781092yyerror(const char *msg)
10791093{
1080- nip2yyerror ("%s", msg);
1094+ nipyyerror ("%s", msg);
10811095}
10821096
10831097InputState *
@@ -1087,7 +1101,7 @@ get_input_state(void)
10871101}
10881102
10891103void
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
10981112void
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 */
11091139void
@@ -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);
0 commit comments