|
|
@ -114,13 +114,17 @@ rsp_threshold = get_rsp_threshold() |
|
|
|
# from, etc.), so it must not be shell quoted. |
|
|
|
# from, etc.), so it must not be shell quoted. |
|
|
|
raw_names = {'DEPFILE_UNQUOTED', 'DESC', 'pool', 'description', 'targetdep'} |
|
|
|
raw_names = {'DEPFILE_UNQUOTED', 'DESC', 'pool', 'description', 'targetdep'} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NINJA_QUOTE_BUILD_PAT = re.compile(r"[$ :\n]") |
|
|
|
|
|
|
|
NINJA_QUOTE_VAR_PAT = re.compile(r"[$ \n]") |
|
|
|
|
|
|
|
|
|
|
|
def ninja_quote(text, is_build_line=False): |
|
|
|
def ninja_quote(text, is_build_line=False): |
|
|
|
if is_build_line: |
|
|
|
if is_build_line: |
|
|
|
qcs = ('$', ' ', ':') |
|
|
|
quote_re = NINJA_QUOTE_BUILD_PAT |
|
|
|
else: |
|
|
|
else: |
|
|
|
qcs = ('$', ' ') |
|
|
|
quote_re = NINJA_QUOTE_VAR_PAT |
|
|
|
for char in qcs: |
|
|
|
# Fast path for when no quoting is necessary |
|
|
|
text = text.replace(char, '$' + char) |
|
|
|
if not quote_re.search(text): |
|
|
|
|
|
|
|
return text |
|
|
|
if '\n' in text: |
|
|
|
if '\n' in text: |
|
|
|
errmsg = '''Ninja does not support newlines in rules. The content was: |
|
|
|
errmsg = '''Ninja does not support newlines in rules. The content was: |
|
|
|
|
|
|
|
|
|
|
@ -128,7 +132,7 @@ def ninja_quote(text, is_build_line=False): |
|
|
|
|
|
|
|
|
|
|
|
Please report this error with a test case to the Meson bug tracker.'''.format(text) |
|
|
|
Please report this error with a test case to the Meson bug tracker.'''.format(text) |
|
|
|
raise MesonException(errmsg) |
|
|
|
raise MesonException(errmsg) |
|
|
|
return text |
|
|
|
return quote_re.sub(r'$\g<0>', text) |
|
|
|
|
|
|
|
|
|
|
|
@unique |
|
|
|
@unique |
|
|
|
class Quoting(Enum): |
|
|
|
class Quoting(Enum): |
|
|
@ -261,18 +265,20 @@ class NinjaRule: |
|
|
|
|
|
|
|
|
|
|
|
# expand variables in command |
|
|
|
# expand variables in command |
|
|
|
command = ' '.join([self._quoter(x) for x in self.command + self.args]) |
|
|
|
command = ' '.join([self._quoter(x) for x in self.command + self.args]) |
|
|
|
expanded_command = '' |
|
|
|
estimate = len(command) |
|
|
|
for m in re.finditer(r'(\${\w*})|(\$\w*)|([^$]*)', command): |
|
|
|
for m in re.finditer(r'(\${\w*}|\$\w*)?[^$]*', command): |
|
|
|
chunk = m.group() |
|
|
|
if m.start(1) != -1: |
|
|
|
if chunk.startswith('$'): |
|
|
|
estimate -= m.end(1) - m.start(1) + 1 |
|
|
|
chunk = chunk[1:] |
|
|
|
chunk = m.group(1) |
|
|
|
chunk = re.sub(r'{(.*)}', r'\1', chunk) |
|
|
|
if chunk[1] == '{': |
|
|
|
chunk = ninja_vars.get(chunk, []) # undefined ninja variables are empty |
|
|
|
chunk = chunk[2:-1] |
|
|
|
chunk = ' '.join(chunk) |
|
|
|
else: |
|
|
|
expanded_command += chunk |
|
|
|
chunk = chunk[1:] |
|
|
|
|
|
|
|
chunk = ninja_vars.get(chunk, []) # undefined ninja variables are empty |
|
|
|
|
|
|
|
estimate += len(' '.join(chunk)) |
|
|
|
|
|
|
|
|
|
|
|
# determine command length |
|
|
|
# determine command length |
|
|
|
return len(expanded_command) |
|
|
|
return estimate |
|
|
|
|
|
|
|
|
|
|
|
class NinjaBuildElement: |
|
|
|
class NinjaBuildElement: |
|
|
|
def __init__(self, all_outputs, outfilenames, rulename, infilenames, implicit_outs=None): |
|
|
|
def __init__(self, all_outputs, outfilenames, rulename, infilenames, implicit_outs=None): |
|
|
@ -380,10 +386,9 @@ class NinjaBuildElement: |
|
|
|
newelems = [] |
|
|
|
newelems = [] |
|
|
|
for i in elems: |
|
|
|
for i in elems: |
|
|
|
if not should_quote or i == '&&': # Hackety hack hack |
|
|
|
if not should_quote or i == '&&': # Hackety hack hack |
|
|
|
quoter = ninja_quote |
|
|
|
newelems.append(ninja_quote(i)) |
|
|
|
else: |
|
|
|
else: |
|
|
|
quoter = lambda x: ninja_quote(qf(x)) |
|
|
|
newelems.append(ninja_quote(qf(i))) |
|
|
|
newelems.append(quoter(i)) |
|
|
|
|
|
|
|
line += ' '.join(newelems) |
|
|
|
line += ' '.join(newelems) |
|
|
|
line += '\n' |
|
|
|
line += '\n' |
|
|
|
outfile.write(line) |
|
|
|
outfile.write(line) |
|
|
|