Skip to content

Commit

Permalink
Allow using '%%' in an output string to mean a single '%' in the outp…
Browse files Browse the repository at this point in the history
…ut file name.

Since output strings are double tup_printf'd to allow for both
%-flags inside $-variables, as well as constructions like $(foo_%f), we
have to make sure that '%%' in an output string aren't expanded by
tup_printf twice.
  • Loading branch information
gittup committed Mar 17, 2024
1 parent cc958da commit 772afcb
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 8 deletions.
29 changes: 21 additions & 8 deletions src/tup/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,13 @@ static char *tup_printf(struct tupfile *tf, const char *cmd, int cmd_len,
struct name_list *nl, struct name_list *onl,
struct name_list *ooinput_nl,
const char *ext, int extlen,
const char *extra_command);
const char *extra_command,
int percpercflag);

enum {
NOEXPAND_PERCPERC,
EXPAND_PERCPERC,
};

static int glob_parse(const char *base, int baselen, char *expanded, int *globidx);

Expand Down Expand Up @@ -2425,7 +2431,7 @@ static int eval_path_list(struct tupfile *tf, struct path_list_head *plist, stru
char *tinput;

if(input_nl) {
tinput = tup_printf(tf, pl->mem, -1, input_nl, NULL, NULL, NULL, 0, NULL);
tinput = tup_printf(tf, pl->mem, -1, input_nl, NULL, NULL, NULL, 0, NULL, EXPAND_PERCPERC);
if(!tinput)
return -1;
} else {
Expand Down Expand Up @@ -3221,7 +3227,7 @@ static int do_rule_outputs(struct tupfile *tf, struct path_list_head *oplist, st
struct path_list *newpl;
char *toutput;

toutput = tup_printf(tf, pl->mem, -1, nl, use_onl, NULL, ext, extlen, NULL);
toutput = tup_printf(tf, pl->mem, -1, nl, use_onl, NULL, ext, extlen, NULL, NOEXPAND_PERCPERC);
if(!toutput)
return -1;
newpl = new_pl(tf, toutput, -1, NULL, pl->orderid);
Expand All @@ -3243,7 +3249,7 @@ static int do_rule_outputs(struct tupfile *tf, struct path_list_head *oplist, st
struct path_list *newpl;
char *toutput;

toutput = tup_printf(tf, pl->mem, -1, nl, use_onl, NULL, ext, extlen, NULL);
toutput = tup_printf(tf, pl->mem, -1, nl, use_onl, NULL, ext, extlen, NULL, EXPAND_PERCPERC);
if(!toutput)
return -1;
newpl = new_pl(tf, toutput, -1, NULL, pl->orderid);
Expand Down Expand Up @@ -3540,7 +3546,7 @@ static int do_rule(struct tupfile *tf, struct rule *r, struct name_list *nl,
}
}

tcmd = tup_printf(tf, cs.cmd, -1, nl, &onl, &r->order_only_inputs, ext, extlen, r->extra_command);
tcmd = tup_printf(tf, cs.cmd, -1, nl, &onl, &r->order_only_inputs, ext, extlen, r->extra_command, EXPAND_PERCPERC);
if(!tcmd)
return -1;
cmd = eval(tf, tcmd, EXPAND_NODES);
Expand All @@ -3549,7 +3555,7 @@ static int do_rule(struct tupfile *tf, struct rule *r, struct name_list *nl,
free(tcmd);

if(cs.display) {
real_display = tup_printf(tf, cs.display, cs.displaylen, nl, &onl, &r->order_only_inputs, ext, extlen, NULL);
real_display = tup_printf(tf, cs.display, cs.displaylen, nl, &onl, &r->order_only_inputs, ext, extlen, NULL, EXPAND_PERCPERC);
if(!real_display)
return -1;
real_displaylen = strlen(real_display);
Expand Down Expand Up @@ -3833,7 +3839,8 @@ static char *tup_printf(struct tupfile *tf, const char *cmd, int cmd_len,
struct name_list *nl, struct name_list *onl,
struct name_list *ooinput_nl,
const char *ext, int extlen,
const char *extra_command)
const char *extra_command,
int expand_percperc)
{
struct name_list_entry *nle;
const char *p;
Expand Down Expand Up @@ -4122,6 +4129,12 @@ static char *tup_printf(struct tupfile *tf, const char *cmd, int cmd_len,
estring_append(&e, "%<", 2);
} else if(*next == '%') {
estring_append(&e, "%", 1);
if(expand_percperc == NOEXPAND_PERCPERC) {
/* If we aren't expanding %% into % yet, keep
* it as %% in the output.
*/
estring_append(&e, "%", 1);
}
} else {
fprintf(tf->f, "tup error: Unknown %%-flag: '%c'\n", *next);
return NULL;
Expand All @@ -4132,7 +4145,7 @@ static char *tup_printf(struct tupfile *tf, const char *cmd, int cmd_len,
if(extra_command) {
char *textra;

textra = tup_printf(tf, extra_command, strlen(extra_command), nl, onl, ooinput_nl, ext, extlen, NULL);
textra = tup_printf(tf, extra_command, strlen(extra_command), nl, onl, ooinput_nl, ext, extlen, NULL, EXPAND_PERCPERC);
if(!textra)
return NULL;
estring_append(&e, " ", 1);
Expand Down
31 changes: 31 additions & 0 deletions test/t2246-percent-percent.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#! /bin/sh -e
# tup - A file-based build system
#
# Copyright (C) 2024 Mike Shal <[email protected]>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

# Try to output a file called '%'

. ./tup.sh

cat > Tupfile << HERE
: |> touch '%o' |> %%
HERE
update

tup_dep_exist . "touch '%'" . '%'
check_exist '%'

eotup

0 comments on commit 772afcb

Please sign in to comment.