1import pytest
2import checkpackagelib.test_util as util
3import checkpackagelib.lib_mk as m
4
5
6DoNotInstallToHostdirUsr = [
7    ('real case',
8     'libapparmor.mk',
9     'LIBAPPARMOR_CONF_OPTS += \\\n'
10     '\t--with-python \\\n'
11     '\tPYTHON=$(HOST_DIR)/usr/bin/python3 \\\n'
12     '\tPYTHON_CONFIG=$(STAGING_DIR)/usr/bin/python3-config \\\n'
13     '\tSWIG=$(SWIG)\n',
14     [['libapparmor.mk:3: install files to $(HOST_DIR)/ instead of $(HOST_DIR)/usr/',
15       '\tPYTHON=$(HOST_DIR)/usr/bin/python3 \\\n']]),
16    ('ignore comment',
17     'any',
18     '# following code do not install to $(HOST_DIR)/usr/\n',
19     []),
20    ]
21
22
23@pytest.mark.parametrize('testname,filename,string,expected', DoNotInstallToHostdirUsr)
24def test_DoNotInstallToHostdirUsr(testname, filename, string, expected):
25    warnings = util.check_file(m.DoNotInstallToHostdirUsr, filename, string)
26    assert warnings == expected
27
28
29Ifdef = [
30    ('ignore commented line',
31     'any',
32     '# ifdef\n',
33     []),
34    ('simple',
35     'any',
36     '\n'
37     'ifdef BR2_PACKAGE_FWTS_EFI_RUNTIME_MODULE\n'
38     'endif\n',
39     [['any:2: use ifeq ($(SYMBOL),y) instead of ifdef SYMBOL',
40       'ifdef BR2_PACKAGE_FWTS_EFI_RUNTIME_MODULE\n']]),
41    ('ignore indentation',
42     'any',
43     '  ifdef FOO\n'
44     '  endif\n'
45     '\tifdef BAR\n'
46     'endif\n',
47     [['any:1: use ifeq ($(SYMBOL),y) instead of ifdef SYMBOL',
48       '  ifdef FOO\n'],
49      ['any:3: use ifeq ($(SYMBOL),y) instead of ifdef SYMBOL',
50       '\tifdef BAR\n']]),
51    ('typo',
52     'any',
53     '\n'
54     'ifndef ($(BR2_ENABLE_LOCALE),y)\n'
55     'endif\n',
56     [['any:2: use ifneq ($(SYMBOL),y) instead of ifndef SYMBOL',
57       'ifndef ($(BR2_ENABLE_LOCALE),y)\n']]),
58    ('else ifdef',
59     'any',
60     'else ifdef  SYMBOL # comment\n',
61     [['any:1: use ifeq ($(SYMBOL),y) instead of ifdef SYMBOL',
62       'else ifdef  SYMBOL # comment\n']]),
63    ('else ifndef',
64     'any',
65     '\t else  ifndef\t($(SYMBOL),y) # comment\n',
66     [['any:1: use ifneq ($(SYMBOL),y) instead of ifndef SYMBOL',
67       '\t else  ifndef\t($(SYMBOL),y) # comment\n']]),
68    ]
69
70
71@pytest.mark.parametrize('testname,filename,string,expected', Ifdef)
72def test_Ifdef(testname, filename, string, expected):
73    warnings = util.check_file(m.Ifdef, filename, string)
74    assert warnings == expected
75
76
77Indent = [
78    ('ignore comment at beginning of line',
79     'any',
80     '# very useful comment\n',
81     []),
82    ('ignore comment at end of line',
83     'any',
84     ' # very useful comment\n',
85     []),
86    ('do not indent on conditional (good)',
87     'any',
88     'ifeq ($(BR2_TOOLCHAIN_HAS_THREADS),y)\n'
89     'FOO_CONF_OPTS += something\n'
90     'endef\n',
91     []),
92    ('do not indent on conditional (bad)',
93     'any',
94     'ifeq ($(BR2_TOOLCHAIN_HAS_THREADS),y)\n'
95     '\tFOO_CONF_OPTS += something\n'
96     'endef\n',
97     [['any:2: unexpected indent with tabs',
98       '\tFOO_CONF_OPTS += something\n']]),
99    ('indent after line that ends in backslash (good)',
100     'any',
101     'FOO_CONF_OPTS += \\\n'
102     '\tsomething\n',
103     []),
104    ('indent after line that ends in backslash (bad)',
105     'any',
106     'FOO_CONF_OPTS += \\\n'
107     'something\n',
108     [['any:2: expected indent with tabs',
109       'something\n']]),
110    ('indent after 2 lines that ends in backslash (good)',
111     'any',
112     'FOO_CONF_OPTS += \\\n'
113     '\tsomething \\\n'
114     '\tsomething_else\n',
115     []),
116    ('indent after 2 lines that ends in backslash (bad)',
117     'any',
118     'FOO_CONF_OPTS += \\\n'
119     '\tsomething \\\n'
120     '\tsomething_else \\\n'
121     'FOO_CONF_OPTS += another_thing\n',
122     [['any:4: expected indent with tabs',
123       'FOO_CONF_OPTS += another_thing\n']]),
124    ('indent inside define (good)',
125     'any',
126     'define FOO_SOMETHING\n'
127     '\tcommand\n'
128     '\tcommand \\\n'
129     '\t\targuments\n'
130     'endef\n'
131     'FOO_POST_PATCH_HOOKS += FOO_SOMETHING\n',
132     []),
133    ('indent inside define (bad, no indent)',
134     'any',
135     'define FOO_SOMETHING\n'
136     'command\n'
137     'endef\n',
138     [['any:2: expected indent with tabs',
139       'command\n']]),
140    ('indent inside define (bad, spaces)',
141     'any',
142     'define FOO_SOMETHING\n'
143     '        command\n'
144     'endef\n',
145     [['any:2: expected indent with tabs',
146       '        command\n']]),
147    ('indent make target (good)',
148     'any',
149     'make_target:\n'
150     '\tcommand\n'
151     '\n',
152     []),
153    ('indent make target (bad)',
154     'any',
155     'make_target:\n'
156     '        command\n'
157     '\n',
158     [['any:2: expected indent with tabs',
159       '        command\n']]),
160    ]
161
162
163@pytest.mark.parametrize('testname,filename,string,expected', Indent)
164def test_Indent(testname, filename, string, expected):
165    warnings = util.check_file(m.Indent, filename, string)
166    assert warnings == expected
167
168
169OverriddenVariable = [
170    ('simple assignment',
171     'any.mk',
172     'VAR_1 = VALUE1\n',
173     []),
174    ('unconditional override (variable without underscore)',
175     'any.mk',
176     'VAR1 = VALUE1\n'
177     'VAR1 = VALUE1\n',
178     [['any.mk:2: unconditional override of variable VAR1',
179       'VAR1 = VALUE1\n']]),
180    ('unconditional override (variable with underscore, same value)',
181     'any.mk',
182     'VAR_1 = VALUE1\n'
183     'VAR_1 = VALUE1\n',
184     [['any.mk:2: unconditional override of variable VAR_1',
185       'VAR_1 = VALUE1\n']]),
186    ('unconditional override (variable with underscore, different value)',
187     'any.mk',
188     'VAR_1 = VALUE1\n'
189     'VAR_1 = VALUE2\n',
190     [['any.mk:2: unconditional override of variable VAR_1',
191       'VAR_1 = VALUE2\n']]),
192    ('warn for unconditional override even with wrong number of spaces',
193     'any.mk',
194     'VAR_1= VALUE1\n'
195     'VAR_1 =VALUE2\n',
196     [['any.mk:2: unconditional override of variable VAR_1',
197       'VAR_1 =VALUE2\n']]),
198    ('warn for := override',
199     'any.mk',
200     'VAR_1 = VALUE1\n'
201     'VAR_1 := VALUE2\n',
202     [['any.mk:2: unconditional override of variable VAR_1',
203       'VAR_1 := VALUE2\n']]),
204    ('append values outside conditional (good)',
205     'any.mk',
206     'VAR_1 = VALUE1\n'
207     'VAR_1 += VALUE2\n',
208     []),
209    ('append values outside conditional (bad)',
210     'any.mk',
211     'VAR_1 = VALUE1\n'
212     'VAR_1 := $(VAR_1), VALUE2\n',
213     [['any.mk:2: unconditional override of variable VAR_1',
214       'VAR_1 := $(VAR_1), VALUE2\n']]),
215    ('immediate assignment inside conditional',
216     'any.mk',
217     'VAR_1 = VALUE1\n'
218     'ifeq (condition)\n'
219     'VAR_1 := $(VAR_1), VALUE2\n',
220     [['any.mk:3: immediate assignment to append to variable VAR_1',
221       'VAR_1 := $(VAR_1), VALUE2\n']]),
222    ('immediate assignment inside conditional and unconditional override outside',
223     'any.mk',
224     'VAR_1 = VALUE1\n'
225     'ifeq (condition)\n'
226     'VAR_1 := $(VAR_1), VALUE2\n'
227     'endif\n'
228     'VAR_1 := $(VAR_1), VALUE2\n',
229     [['any.mk:3: immediate assignment to append to variable VAR_1',
230       'VAR_1 := $(VAR_1), VALUE2\n'],
231      ['any.mk:5: unconditional override of variable VAR_1',
232       'VAR_1 := $(VAR_1), VALUE2\n']]),
233    ]
234
235
236@pytest.mark.parametrize('testname,filename,string,expected', OverriddenVariable)
237def test_OverriddenVariable(testname, filename, string, expected):
238    warnings = util.check_file(m.OverriddenVariable, filename, string)
239    assert warnings == expected
240
241
242PackageHeader = [
243    ('first line (good)',
244     'any',
245     80 * '#' + '\n',
246     []),
247    ('first line (bad)',
248     'any',
249     '# very useful comment\n',
250     [['any:1: should be 80 hashes (url#writing-rules-mk)',
251       '# very useful comment\n',
252       80 * '#']]),
253    ('second line (bad)',
254     'any',
255     80 * '#' + '\n'
256     '# package\n',
257     [['any:2: should be 1 hash (url#writing-rules-mk)',
258       '# package\n']]),
259    ('full header (good)',
260     'any',
261     80 * '#' + '\n'
262     '#\n'
263     '# package\n'
264     '#\n' +
265     80 * '#' + '\n'
266     '\n',
267     []),
268    ('blank line after header (good)',
269     'any',
270     80 * '#' + '\n'
271     '#\n'
272     '# package\n'
273     '#\n' +
274     80 * '#' + '\n'
275     '\n'
276     'FOO_VERSION = 1\n',
277     []),
278    ('blank line after header (bad)',
279     'any',
280     80 * '#' + '\n'
281     '#\n'
282     '# package\n'
283     '#\n' +
284     80 * '#' + '\n'
285     'FOO_VERSION = 1\n',
286     [['any:6: should be a blank line (url#writing-rules-mk)',
287       'FOO_VERSION = 1\n']]),
288    ('wrong number of hashes',
289     'any',
290     79 * '#' + '\n'
291     '#\n'
292     '# package\n'
293     '#\n' +
294     81 * '#' + '\n'
295     '\n',
296     [['any:1: should be 80 hashes (url#writing-rules-mk)',
297       79 * '#' + '\n',
298       80 * '#'],
299      ['any:5: should be 80 hashes (url#writing-rules-mk)',
300       81 * '#' + '\n',
301       80 * '#']]),
302    ('allow include without header',
303     'any',
304     'include $(sort $(wildcard package/foo/*/*.mk))\n',
305     []),
306    ]
307
308
309@pytest.mark.parametrize('testname,filename,string,expected', PackageHeader)
310def test_PackageHeader(testname, filename, string, expected):
311    warnings = util.check_file(m.PackageHeader, filename, string)
312    assert warnings == expected
313
314
315RemoveDefaultPackageSourceVariable = [
316    ('bad',
317     'any.mk',
318     'ANY_SOURCE = any-$(ANY_VERSION).tar.gz\n',
319     [['any.mk:1: remove default value of _SOURCE variable (url#generic-package-reference)',
320       'ANY_SOURCE = any-$(ANY_VERSION).tar.gz\n']]),
321    ('bad with path',
322     './any.mk',
323     'ANY_SOURCE = any-$(ANY_VERSION).tar.gz\n',
324     [['./any.mk:1: remove default value of _SOURCE variable (url#generic-package-reference)',
325       'ANY_SOURCE = any-$(ANY_VERSION).tar.gz\n']]),
326    ('warn for correct line',
327     './any.mk',
328     '\n'
329     '\n'
330     '\n'
331     'ANY_SOURCE = any-$(ANY_VERSION).tar.gz\n',
332     [['./any.mk:4: remove default value of _SOURCE variable (url#generic-package-reference)',
333       'ANY_SOURCE = any-$(ANY_VERSION).tar.gz\n']]),
334    ('warn ignoring missing spaces',
335     './any.mk',
336     'ANY_SOURCE=any-$(ANY_VERSION).tar.gz\n',
337     [['./any.mk:1: remove default value of _SOURCE variable (url#generic-package-reference)',
338       'ANY_SOURCE=any-$(ANY_VERSION).tar.gz\n']]),
339    ('good',
340     './any.mk',
341     'ANY_SOURCE = aNy-$(ANY_VERSION).tar.gz\n',
342     []),
343    ('gcc exception',
344     'gcc.mk',
345     'GCC_SOURCE = gcc-$(GCC_VERSION).tar.gz\n',
346     []),
347    ('binutils exception',
348     './binutils.mk',
349     'BINUTILS_SOURCE = binutils-$(BINUTILS_VERSION).tar.gz\n',
350     []),
351    ('gdb exception',
352     'gdb/gdb.mk',
353     'GDB_SOURCE = gdb-$(GDB_VERSION).tar.gz\n',
354     []),
355    ('package name with dash',
356     'python-subprocess32.mk',
357     'PYTHON_SUBPROCESS32_SOURCE = python-subprocess32-$(PYTHON_SUBPROCESS32_VERSION).tar.gz\n',
358     [['python-subprocess32.mk:1: remove default value of _SOURCE variable (url#generic-package-reference)',
359       'PYTHON_SUBPROCESS32_SOURCE = python-subprocess32-$(PYTHON_SUBPROCESS32_VERSION).tar.gz\n']]),
360    ]
361
362
363@pytest.mark.parametrize('testname,filename,string,expected', RemoveDefaultPackageSourceVariable)
364def test_RemoveDefaultPackageSourceVariable(testname, filename, string, expected):
365    warnings = util.check_file(m.RemoveDefaultPackageSourceVariable, filename, string)
366    assert warnings == expected
367
368
369SpaceBeforeBackslash = [
370    ('no backslash',
371     'any.mk',
372     '\n',
373     []),
374    ('ignore missing indent',
375     'any.mk',
376     'define ANY_SOME_FIXUP\n'
377     'for i in $$(find $(STAGING_DIR)/usr/lib* -name "any*.la"); do \\\n',
378     []),
379    ('ignore missing space',
380     'any.mk',
381     'ANY_CONF_ENV= \\\n'
382     '\tap_cv_void_ptr_lt_long=no \\\n',
383     []),
384    ('variable',
385     'any.mk',
386     '\n'
387     'ANY = \\\n',
388     []),
389    ('2 spaces',
390     'any.mk',
391     'ANY =  \\\n',
392     [['any.mk:1: use only one space before backslash',
393       'ANY =  \\\n']]),
394    ('warn about correct line',
395     'any.mk',
396     '\n'
397     'ANY =  \\\n',
398     [['any.mk:2: use only one space before backslash',
399       'ANY =  \\\n']]),
400    ('tab',
401     'any.mk',
402     'ANY =\t\\\n',
403     [['any.mk:1: use only one space before backslash',
404       'ANY =\t\\\n']]),
405    ('tabs',
406     'any.mk',
407     'ANY =\t\t\\\n',
408     [['any.mk:1: use only one space before backslash',
409       'ANY =\t\t\\\n']]),
410    ('spaces and tabs',
411     'any.mk',
412     'ANY =  \t\t\\\n',
413     [['any.mk:1: use only one space before backslash',
414       'ANY =  \t\t\\\n']]),
415    ('mixed spaces and tabs 1',
416     'any.mk',
417     'ANY = \t \t\\\n',
418     [['any.mk:1: use only one space before backslash',
419       'ANY = \t \t\\\n']]),
420    ('mixed spaces and tabs 2',
421     'any.mk',
422     'ANY = \t  \\\n',
423     [['any.mk:1: use only one space before backslash',
424       'ANY = \t  \\\n']]),
425    ]
426
427
428@pytest.mark.parametrize('testname,filename,string,expected', SpaceBeforeBackslash)
429def test_SpaceBeforeBackslash(testname, filename, string, expected):
430    warnings = util.check_file(m.SpaceBeforeBackslash, filename, string)
431    assert warnings == expected
432
433
434TrailingBackslash = [
435    ('no backslash',
436     'any.mk',
437     'ANY = \n',
438     []),
439    ('one line',
440     'any.mk',
441     'ANY = \\\n',
442     []),
443    ('2 lines',
444     'any.mk',
445     'ANY = \\\n'
446     '\\\n',
447     []),
448    ('empty line after',
449     'any.mk',
450     'ANY = \\\n'
451     '\n',
452     [['any.mk:1: remove trailing backslash',
453       'ANY = \\\n']]),
454    ('line with spaces after',
455     'any.mk',
456     'ANY = \\\n'
457     '     \n',
458     [['any.mk:1: remove trailing backslash',
459       'ANY = \\\n']]),
460    ('line with tabs after',
461     'any.mk',
462     'ANY = \\\n'
463     '\t\n',
464     [['any.mk:1: remove trailing backslash',
465       'ANY = \\\n']]),
466    ('ignore if commented',
467     'any.mk',
468     '# ANY = \\\n'
469     '\n',
470     []),
471    ('real example',
472     'any.mk',
473     'ANY_CONF_ENV= \t\\\n'
474     '\tap_cv_void_ptr_lt_long=no  \\\n'
475     '\n',
476     [['any.mk:2: remove trailing backslash',
477       '\tap_cv_void_ptr_lt_long=no  \\\n']]),
478    ('ignore whitespace 1',
479     'any.mk',
480     'ANY =  \t\t\\\n',
481     []),
482    ('ignore whitespace 2',
483     'any.mk',
484     'ANY = \t \t\\\n',
485     []),
486    ('ignore whitespace 3',
487     'any.mk',
488     'ANY = \t  \\\n',
489     []),
490    ]
491
492
493@pytest.mark.parametrize('testname,filename,string,expected', TrailingBackslash)
494def test_TrailingBackslash(testname, filename, string, expected):
495    warnings = util.check_file(m.TrailingBackslash, filename, string)
496    assert warnings == expected
497
498
499TypoInPackageVariable = [
500    ('good',
501     'any.mk',
502     'ANY_VAR = \n',
503     []),
504    ('good with path 1',
505     './any.mk',
506     'ANY_VAR += \n',
507     []),
508    ('good with path 2',
509     'any/any.mk',
510     'ANY_VAR = \n',
511     []),
512    ('bad =',
513     'any.mk',
514     'OTHER_VAR = \n',
515     [['any.mk:1: possible typo: OTHER_VAR -> *ANY*',
516       'OTHER_VAR = \n']]),
517    ('bad +=',
518     'any.mk',
519     'OTHER_VAR += \n',
520     [['any.mk:1: possible typo: OTHER_VAR -> *ANY*',
521       'OTHER_VAR += \n']]),
522    ('ignore missing space',
523     'any.mk',
524     'OTHER_VAR= \n',
525     [['any.mk:1: possible typo: OTHER_VAR -> *ANY*',
526       'OTHER_VAR= \n']]),
527    ('use path in the warning',
528     './any.mk',
529     'OTHER_VAR = \n',
530     [['./any.mk:1: possible typo: OTHER_VAR -> *ANY*',
531       'OTHER_VAR = \n']]),
532    ('another name',
533     'other.mk',
534     'ANY_VAR = \n',
535     [['other.mk:1: possible typo: ANY_VAR -> *OTHER*',
536       'ANY_VAR = \n']]),
537    ('libc exception',
538     './any.mk',
539     'BR_LIBC = \n',
540     []),
541    ('rootfs exception',
542     'any.mk',
543     'ROOTFS_ANY_VAR += \n',
544     []),
545    ('host (good)',
546     'any.mk',
547     'HOST_ANY_VAR += \n',
548     []),
549    ('host (bad)',
550     'any.mk',
551     'HOST_OTHER_VAR = \n',
552     [['any.mk:1: possible typo: HOST_OTHER_VAR -> *ANY*',
553       'HOST_OTHER_VAR = \n']]),
554    ('provides',
555     'any.mk',
556     'ANY_PROVIDES = other thing\n'
557     'OTHER_VAR = \n',
558     []),
559    ('ignore space',
560     'any.mk',
561     'ANY_PROVIDES  =  thing  other \n'
562     'OTHER_VAR = \n',
563     []),
564    ('wrong provides',
565     'any.mk',
566     'ANY_PROVIDES = other\n'
567     'OTHERS_VAR = \n',
568     [['any.mk:2: possible typo: OTHERS_VAR -> *ANY*',
569       'OTHERS_VAR = \n']]),
570    ]
571
572
573@pytest.mark.parametrize('testname,filename,string,expected', TypoInPackageVariable)
574def test_TypoInPackageVariable(testname, filename, string, expected):
575    warnings = util.check_file(m.TypoInPackageVariable, filename, string)
576    assert warnings == expected
577
578
579UselessFlag = [
580    ('autoreconf no',
581     'any.mk',
582     'ANY_AUTORECONF=NO\n',
583     [['any.mk:1: useless default value (url#_infrastructure_for_autotools_based_packages)',
584       'ANY_AUTORECONF=NO\n']]),
585    ('host autoreconf no',
586     'any.mk',
587     'HOST_ANY_AUTORECONF\n',
588     []),
589    ('autoreconf yes',
590     'any.mk',
591     'ANY_AUTORECONF=YES\n',
592     []),
593    ('libtool_patch yes',
594     'any.mk',
595     'ANY_LIBTOOL_PATCH\t=  YES\n',
596     [['any.mk:1: useless default value (url#_infrastructure_for_autotools_based_packages)',
597       'ANY_LIBTOOL_PATCH\t=  YES\n']]),
598    ('libtool_patch no',
599     'any.mk',
600     'ANY_LIBTOOL_PATCH= \t NO\n',
601     []),
602    ('generic',
603     'any.mk',
604     'ANY_INSTALL_IMAGES = NO\n'
605     'ANY_INSTALL_REDISTRIBUTE = YES\n'
606     'ANY_INSTALL_STAGING = NO\n'
607     'ANY_INSTALL_TARGET = YES\n',
608     [['any.mk:1: useless default value (url#_infrastructure_for_packages_with_specific_build_systems)',
609       'ANY_INSTALL_IMAGES = NO\n'],
610      ['any.mk:2: useless default value (url#_infrastructure_for_packages_with_specific_build_systems)',
611       'ANY_INSTALL_REDISTRIBUTE = YES\n'],
612      ['any.mk:3: useless default value (url#_infrastructure_for_packages_with_specific_build_systems)',
613       'ANY_INSTALL_STAGING = NO\n'],
614      ['any.mk:4: useless default value (url#_infrastructure_for_packages_with_specific_build_systems)',
615       'ANY_INSTALL_TARGET = YES\n']]),
616    ('conditional',
617     'any.mk',
618     'ifneq (condition)\n'
619     'ANY_INSTALL_IMAGES = NO\n'
620     'endif\n'
621     'ANY_INSTALL_REDISTRIBUTE = YES\n',
622     [['any.mk:4: useless default value (url#_infrastructure_for_packages_with_specific_build_systems)',
623       'ANY_INSTALL_REDISTRIBUTE = YES\n']]),
624    ]
625
626
627@pytest.mark.parametrize('testname,filename,string,expected', UselessFlag)
628def test_UselessFlag(testname, filename, string, expected):
629    warnings = util.check_file(m.UselessFlag, filename, string)
630    assert warnings == expected
631
632
633VariableWithBraces = [
634    ('good',
635     'xmlstarlet.mk',
636     'XMLSTARLET_CONF_OPTS += \\\n'
637     '\t--with-libxml-prefix=$(STAGING_DIR)/usr \\\n',
638     []),
639    ('bad',
640     'xmlstarlet.mk',
641     'XMLSTARLET_CONF_OPTS += \\\n'
642     '\t--with-libxml-prefix=${STAGING_DIR}/usr \\\n',
643     [['xmlstarlet.mk:2: use $() to delimit variables, not ${}',
644       '\t--with-libxml-prefix=${STAGING_DIR}/usr \\\n']]),
645    ('expanded by the shell',
646     'sg3_utils.mk',
647     '\tfor prog in xcopy zone; do \\\n'
648     '\t\t$(RM) $(TARGET_DIR)/usr/bin/sg_$${prog} ; \\\n'
649     '\tdone\n',
650     []),
651    ('comments',
652     'any.mk',
653     '#\t--with-libxml-prefix=${STAGING_DIR}/usr \\\n',
654     []),
655    ]
656
657
658@pytest.mark.parametrize('testname,filename,string,expected', VariableWithBraces)
659def test_VariableWithBraces(testname, filename, string, expected):
660    warnings = util.check_file(m.VariableWithBraces, filename, string)
661    assert warnings == expected
662