xref: /OK3568_Linux_fs/yocto/meta-openembedded/contrib/oe-stylize.py (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun#!/usr/bin/env python
2*4882a593Smuzhiyun
3*4882a593Smuzhiyun"""\
4*4882a593SmuzhiyunSanitize a bitbake file following the OpenEmbedded style guidelines,
5*4882a593Smuzhiyunsee http://openembedded.org/wiki/StyleGuide
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun(C) 2006 Cyril Romain <cyril.romain@gmail.com>
8*4882a593SmuzhiyunMIT license
9*4882a593Smuzhiyun
10*4882a593SmuzhiyunTODO:
11*4882a593Smuzhiyun - add the others OpenEmbedded variables commonly used:
12*4882a593Smuzhiyun - parse command arguments and print usage on misuse
13*4882a593Smuzhiyun    . prevent giving more than one .bb file in arguments
14*4882a593Smuzhiyun - write result to a file
15*4882a593Smuzhiyun - backup the original .bb file
16*4882a593Smuzhiyun - make a diff and ask confirmation for patching ?
17*4882a593Smuzhiyun - do not use startswith only:
18*4882a593Smuzhiyun    /!\ startswith('SOMETHING') is not taken into account due to the previous startswith('S').
19*4882a593Smuzhiyun - count rule breaks and displays them in the order frequence
20*4882a593Smuzhiyun"""
21*4882a593Smuzhiyun
22*4882a593Smuzhiyunfrom __future__ import print_function
23*4882a593Smuzhiyunimport fileinput
24*4882a593Smuzhiyunimport string
25*4882a593Smuzhiyunimport re
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun__author__ = "Cyril Romain <cyril.romain@gmail.com>"
28*4882a593Smuzhiyun__version__ = "$Revision: 0.5 $"
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun# The standard set of variables often found in .bb files in the preferred order
31*4882a593SmuzhiyunOE_vars = [
32*4882a593Smuzhiyun    'SUMMARY',
33*4882a593Smuzhiyun    'DESCRIPTION',
34*4882a593Smuzhiyun    'AUTHOR',
35*4882a593Smuzhiyun    'HOMEPAGE',
36*4882a593Smuzhiyun    'SECTION',
37*4882a593Smuzhiyun    'LICENSE',
38*4882a593Smuzhiyun    'LIC_FILES_CHKSUM',
39*4882a593Smuzhiyun    'DEPENDS',
40*4882a593Smuzhiyun    'PROVIDES',
41*4882a593Smuzhiyun    'SRCREV',
42*4882a593Smuzhiyun    'SRCDATE',
43*4882a593Smuzhiyun    'PE',
44*4882a593Smuzhiyun    'PV',
45*4882a593Smuzhiyun    'PR',
46*4882a593Smuzhiyun    'INC_PR',
47*4882a593Smuzhiyun    'SRC_URI',
48*4882a593Smuzhiyun    'S',
49*4882a593Smuzhiyun    'GPE_TARBALL_SUFFIX',
50*4882a593Smuzhiyun    'inherit',
51*4882a593Smuzhiyun    'EXTRA_',
52*4882a593Smuzhiyun    'export',
53*4882a593Smuzhiyun    'do_fetch',
54*4882a593Smuzhiyun    'do_unpack',
55*4882a593Smuzhiyun    'do_patch',
56*4882a593Smuzhiyun    'WORKDIR',
57*4882a593Smuzhiyun    'acpaths',
58*4882a593Smuzhiyun    'do_configure',
59*4882a593Smuzhiyun    'do_compile',
60*4882a593Smuzhiyun    'do_install',
61*4882a593Smuzhiyun    'PACKAGES',
62*4882a593Smuzhiyun    'PACKAGE_ARCH',
63*4882a593Smuzhiyun    'RDEPENDS',
64*4882a593Smuzhiyun    'RRECOMMENDS',
65*4882a593Smuzhiyun    'RSUGGESTS',
66*4882a593Smuzhiyun    'RPROVIDES',
67*4882a593Smuzhiyun    'RCONFLICTS',
68*4882a593Smuzhiyun    'FILES',
69*4882a593Smuzhiyun    'do_package',
70*4882a593Smuzhiyun    'do_stage',
71*4882a593Smuzhiyun    'addhandler',
72*4882a593Smuzhiyun    'addtask',
73*4882a593Smuzhiyun    'bindir',
74*4882a593Smuzhiyun    'headers',
75*4882a593Smuzhiyun    'include',
76*4882a593Smuzhiyun    'includedir',
77*4882a593Smuzhiyun    'python',
78*4882a593Smuzhiyun    'qtopiadir',
79*4882a593Smuzhiyun    'pkg_preins',
80*4882a593Smuzhiyun    'pkg_prerm',
81*4882a593Smuzhiyun    'pkg_postins',
82*4882a593Smuzhiyun    'pkg_postrm',
83*4882a593Smuzhiyun    'require',
84*4882a593Smuzhiyun    'sbindir',
85*4882a593Smuzhiyun    'basesysconfdir',
86*4882a593Smuzhiyun    'sysconfdir',
87*4882a593Smuzhiyun    'ALLOW_EMPTY',
88*4882a593Smuzhiyun    'ALTERNATIVE_NAME',
89*4882a593Smuzhiyun    'ALTERNATIVE_PATH',
90*4882a593Smuzhiyun    'ALTERNATIVE_LINK',
91*4882a593Smuzhiyun    'ALTERNATIVE_PRIORITY',
92*4882a593Smuzhiyun    'ALTNAME',
93*4882a593Smuzhiyun    'AMD_DRIVER_LABEL',
94*4882a593Smuzhiyun    'AMD_DRIVER_VERSION',
95*4882a593Smuzhiyun    'ANGSTROM_EXTRA_INSTALL',
96*4882a593Smuzhiyun    'APPDESKTOP',
97*4882a593Smuzhiyun    'APPIMAGE',
98*4882a593Smuzhiyun    'APPNAME',
99*4882a593Smuzhiyun    'APPTYPE',
100*4882a593Smuzhiyun    'APPWEB_BUILD',
101*4882a593Smuzhiyun    'APPWEB_HOST',
102*4882a593Smuzhiyun    'AR',
103*4882a593Smuzhiyun    'ARCH',
104*4882a593Smuzhiyun    'ARM_INSTRUCTION_SET',
105*4882a593Smuzhiyun    'MIPS_INSTRUCTION_SET',
106*4882a593Smuzhiyun    'ARM_MUTEX',
107*4882a593Smuzhiyun    'ART_CONFIG',
108*4882a593Smuzhiyun    'B',
109*4882a593Smuzhiyun    'BJAM_OPTS',
110*4882a593Smuzhiyun    'BJAM_TOOLS',
111*4882a593Smuzhiyun    'BONOBO_HEADERS',
112*4882a593Smuzhiyun    'BOOTSCRIPTS',
113*4882a593Smuzhiyun    'BROKEN',
114*4882a593Smuzhiyun    'BUILD_CPPFLAGS',
115*4882a593Smuzhiyun    'CFLAGS',
116*4882a593Smuzhiyun    'CCFLAGS',
117*4882a593Smuzhiyun    'CMDLINE',
118*4882a593Smuzhiyun    'COLLIE_MEMORY_SIZE',
119*4882a593Smuzhiyun    'COMPATIBLE_HOST',
120*4882a593Smuzhiyun    'COMPATIBLE_MACHINE',
121*4882a593Smuzhiyun    'COMPILE_HERMES',
122*4882a593Smuzhiyun    'CONFFILES',
123*4882a593Smuzhiyun    'CONFLICTS',
124*4882a593Smuzhiyun    'CORE_EXTRA_D',
125*4882a593Smuzhiyun    'CORE_IMAGE_EXTRA_INSTALL',
126*4882a593Smuzhiyun    'CORE_PACKAGES_D',
127*4882a593Smuzhiyun    'CORE_PACKAGES_RD',
128*4882a593Smuzhiyun    'CPPFLAGS',
129*4882a593Smuzhiyun    'CVSDATE',
130*4882a593Smuzhiyun    'CXXFLAGS',
131*4882a593Smuzhiyun    'DEBIAN_NOAUTONAME',
132*4882a593Smuzhiyun    'DEBUG_APPS',
133*4882a593Smuzhiyun    'DEFAULT_PREFERENCE',
134*4882a593Smuzhiyun    'DB4_CONFIG',
135*4882a593Smuzhiyun    'EXCLUDE_FROM_SHLIBS',
136*4882a593Smuzhiyun    'EXCLUDE_FROM_WORLD',
137*4882a593Smuzhiyun    'FIXEDSRCDATE',
138*4882a593Smuzhiyun    'GLIBC_ADDONS',
139*4882a593Smuzhiyun    'GLIBC_EXTRA_OECONF',
140*4882a593Smuzhiyun    'GNOME_VFS_HEADERS',
141*4882a593Smuzhiyun    'HEADERS',
142*4882a593Smuzhiyun    'INHIBIT_DEFAULT_DEPS',
143*4882a593Smuzhiyun    'INITSCRIPT_PACKAGES',
144*4882a593Smuzhiyun    'INITSCRIPT_NAME',
145*4882a593Smuzhiyun    'INITSCRIPT_PARAMS',
146*4882a593Smuzhiyun    'INSANE_SKIP',
147*4882a593Smuzhiyun    'PACKAGE_INSTALL',
148*4882a593Smuzhiyun    'KERNEL_IMAGETYPE',
149*4882a593Smuzhiyun    'KERNEL_IMAGEDEST',
150*4882a593Smuzhiyun    'KERNEL_OUTPUT',
151*4882a593Smuzhiyun    'KERNEL_RELEASE',
152*4882a593Smuzhiyun    'KERNEL_PRIORITY',
153*4882a593Smuzhiyun    'KERNEL_SOURCE',
154*4882a593Smuzhiyun    'KERNEL_SUFFIX',
155*4882a593Smuzhiyun    'KERNEL_VERSION',
156*4882a593Smuzhiyun    'K_MAJOR',
157*4882a593Smuzhiyun    'K_MICRO',
158*4882a593Smuzhiyun    'K_MINOR',
159*4882a593Smuzhiyun    'HHV',
160*4882a593Smuzhiyun    'KV',
161*4882a593Smuzhiyun    'LDFLAGS',
162*4882a593Smuzhiyun    'LD',
163*4882a593Smuzhiyun    'LD_SO',
164*4882a593Smuzhiyun    'LDLIBS',
165*4882a593Smuzhiyun    'LEAD_SONAME',
166*4882a593Smuzhiyun    'LIBTOOL',
167*4882a593Smuzhiyun    'LIBBDB_EXTRA',
168*4882a593Smuzhiyun    'LIBV',
169*4882a593Smuzhiyun    'MACHINE_ESSENTIAL_EXTRA_RDEPENDS',
170*4882a593Smuzhiyun    'MACHINE_ESSENTIAL_EXTRA_RRECOMMENDS',
171*4882a593Smuzhiyun    'MACHINE_EXTRA_RDEPENDS',
172*4882a593Smuzhiyun    'MACHINE_EXTRA_RRECOMMENDS',
173*4882a593Smuzhiyun    'MACHINE_FEATURES',
174*4882a593Smuzhiyun    'MACHINE_TASKS',
175*4882a593Smuzhiyun    'MACHINE',
176*4882a593Smuzhiyun    'MACHTYPE',
177*4882a593Smuzhiyun    'MAKE_TARGETS',
178*4882a593Smuzhiyun    'MESSAGEUSER',
179*4882a593Smuzhiyun    'MESSAGEHOME',
180*4882a593Smuzhiyun    'MIRRORS',
181*4882a593Smuzhiyun    'MUTEX',
182*4882a593Smuzhiyun    'OE_QMAKE_INCDIR_QT',
183*4882a593Smuzhiyun    'OE_QMAKE_CXXFLAGS',
184*4882a593Smuzhiyun    'ORBIT_IDL_SRC',
185*4882a593Smuzhiyun    'PARALLEL_MAKE',
186*4882a593Smuzhiyun    'PAKCAGE_ARCH',
187*4882a593Smuzhiyun    'PCMCIA_MANAGER',
188*4882a593Smuzhiyun    'PKG_BASENAME',
189*4882a593Smuzhiyun    'PKG',
190*4882a593Smuzhiyun    'QEMU',
191*4882a593Smuzhiyun    'QMAKE_PROFILES',
192*4882a593Smuzhiyun    'QPEDIR',
193*4882a593Smuzhiyun    'QPF_DESCRIPTION',
194*4882a593Smuzhiyun    'QPF_PKGPATTERN',
195*4882a593Smuzhiyun    'QT_CONFIG_FLAGS',
196*4882a593Smuzhiyun    'QT_LIBRARY',
197*4882a593Smuzhiyun    'ROOTFS_POSTPROCESS_COMMAND',
198*4882a593Smuzhiyun    'RREPLACES',
199*4882a593Smuzhiyun    'TARGET_CFLAGS',
200*4882a593Smuzhiyun    'TARGET_CPPFLAGS',
201*4882a593Smuzhiyun    'TARGET_LDFLAGS',
202*4882a593Smuzhiyun    'UBOOT_MACHINE',
203*4882a593Smuzhiyun    'UCLIBC_BASE',
204*4882a593Smuzhiyun    'UCLIBC_PATCHES',
205*4882a593Smuzhiyun    'USERADD_PACKAGES',
206*4882a593Smuzhiyun    'USERADD_PARAM',
207*4882a593Smuzhiyun    'VIRTUAL_NAME',
208*4882a593Smuzhiyun    'XORG_PN',
209*4882a593Smuzhiyun    'XSERVER',
210*4882a593Smuzhiyun    'others'
211*4882a593Smuzhiyun]
212*4882a593Smuzhiyun
213*4882a593SmuzhiyunvarRegexp = r'^([a-zA-Z_0-9${}:-]*)([ \t]*)([+.:]?=[+.]?)([ \t]*)([^\t]+)'
214*4882a593SmuzhiyunroutineRegexp = r'^([a-zA-Z0-9_ ${}:-]+?)\('
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun# Variables seen in the processed .bb
217*4882a593Smuzhiyunseen_vars = {}
218*4882a593Smuzhiyunfor v in OE_vars:
219*4882a593Smuzhiyun    seen_vars[v] = []
220*4882a593Smuzhiyun
221*4882a593Smuzhiyun# _Format guideline #0_:
222*4882a593Smuzhiyun#   No spaces are allowed at the beginning of lines that define a variable or
223*4882a593Smuzhiyun#   a do_ routine
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun
226*4882a593Smuzhiyundef respect_rule0(line):
227*4882a593Smuzhiyun    return line.lstrip() == line
228*4882a593Smuzhiyun
229*4882a593Smuzhiyun
230*4882a593Smuzhiyundef conformTo_rule0(line):
231*4882a593Smuzhiyun    return line.lstrip()
232*4882a593Smuzhiyun
233*4882a593Smuzhiyun# _Format guideline #1_:
234*4882a593Smuzhiyun#   No spaces are allowed behind the line continuation symbol '\'
235*4882a593Smuzhiyun
236*4882a593Smuzhiyun
237*4882a593Smuzhiyundef respect_rule1(line):
238*4882a593Smuzhiyun    if line.rstrip().endswith('\\'):
239*4882a593Smuzhiyun        return line.endswith('\\')
240*4882a593Smuzhiyun    else:
241*4882a593Smuzhiyun        return True
242*4882a593Smuzhiyun
243*4882a593Smuzhiyun
244*4882a593Smuzhiyundef conformTo_rule1(line):
245*4882a593Smuzhiyun    return line.rstrip()
246*4882a593Smuzhiyun
247*4882a593Smuzhiyun# _Format guideline #2_:
248*4882a593Smuzhiyun#   Tabs should not be used (use spaces instead).
249*4882a593Smuzhiyun
250*4882a593Smuzhiyun
251*4882a593Smuzhiyundef respect_rule2(line):
252*4882a593Smuzhiyun    return line.count('\t') == 0
253*4882a593Smuzhiyun
254*4882a593Smuzhiyun
255*4882a593Smuzhiyundef conformTo_rule2(line):
256*4882a593Smuzhiyun    return line.expandtabs()
257*4882a593Smuzhiyun
258*4882a593Smuzhiyun# _Format guideline #3_:
259*4882a593Smuzhiyun#   Comments inside bb files are allowed using the '#' character at the
260*4882a593Smuzhiyun#   beginning of a line.
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun
263*4882a593Smuzhiyundef respect_rule3(line):
264*4882a593Smuzhiyun    if line.lstrip().startswith('#'):
265*4882a593Smuzhiyun        return line.startswith('#')
266*4882a593Smuzhiyun    else:
267*4882a593Smuzhiyun        return True
268*4882a593Smuzhiyun
269*4882a593Smuzhiyun
270*4882a593Smuzhiyundef conformTo_rule3(line):
271*4882a593Smuzhiyun    return line.lstrip()
272*4882a593Smuzhiyun
273*4882a593Smuzhiyun# _Format guideline #4_:
274*4882a593Smuzhiyun#   Use quotes on the right hand side of assignments FOO = "BAR"
275*4882a593Smuzhiyun
276*4882a593Smuzhiyun
277*4882a593Smuzhiyundef respect_rule4(line):
278*4882a593Smuzhiyun    r = re.search(varRegexp, line)
279*4882a593Smuzhiyun    if r is not None:
280*4882a593Smuzhiyun        r2 = re.search(r'("?)([^"\\]*)(["\\]?)', r.group(5))
281*4882a593Smuzhiyun        # do not test for None it because always match
282*4882a593Smuzhiyun        return r2.group(1) == '"' and r2.group(3) != ''
283*4882a593Smuzhiyun    return False
284*4882a593Smuzhiyun
285*4882a593Smuzhiyun
286*4882a593Smuzhiyundef conformTo_rule4(line):
287*4882a593Smuzhiyun    r = re.search(varRegexp, line)
288*4882a593Smuzhiyun    return ''.join([r.group(1), ' ', r.group(3), ' "', r.group(5), r.group(5).endswith('"') and '' or '"'])
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun# _Format guideline #5_:
291*4882a593Smuzhiyun#   The correct spacing for a variable is FOO = "BAR".
292*4882a593Smuzhiyun
293*4882a593Smuzhiyun
294*4882a593Smuzhiyundef respect_rule5(line):
295*4882a593Smuzhiyun    r = re.search(varRegexp, line)
296*4882a593Smuzhiyun    return r is not None and r.group(2) == " " and r.group(4) == " "
297*4882a593Smuzhiyun
298*4882a593Smuzhiyun
299*4882a593Smuzhiyundef conformTo_rule5(line):
300*4882a593Smuzhiyun    r = re.search(varRegexp, line)
301*4882a593Smuzhiyun    return ''.join([r.group(1), ' ', r.group(3), ' ', r.group(5)])
302*4882a593Smuzhiyun
303*4882a593Smuzhiyun# _Format guideline #6_:
304*4882a593Smuzhiyun#   Don't use spaces or tabs on empty lines
305*4882a593Smuzhiyun
306*4882a593Smuzhiyun
307*4882a593Smuzhiyundef respect_rule6(line):
308*4882a593Smuzhiyun    return not line.isspace() or line == "\n"
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun
311*4882a593Smuzhiyundef conformTo_rule6(line):
312*4882a593Smuzhiyun    return ""
313*4882a593Smuzhiyun
314*4882a593Smuzhiyun# _Format guideline #7_:
315*4882a593Smuzhiyun#   Indentation of multiline variables such as SRC_URI is desireable.
316*4882a593Smuzhiyun
317*4882a593Smuzhiyun
318*4882a593Smuzhiyundef respect_rule7(line):
319*4882a593Smuzhiyun    return True
320*4882a593Smuzhiyun
321*4882a593Smuzhiyun
322*4882a593Smuzhiyundef conformTo_rule7(line):
323*4882a593Smuzhiyun    return line
324*4882a593Smuzhiyun
325*4882a593Smuzhiyun
326*4882a593Smuzhiyunrules = (
327*4882a593Smuzhiyun    (respect_rule0, conformTo_rule0, "No spaces are allowed at the beginning of lines that define a variable or a do_ routine"),
328*4882a593Smuzhiyun    (respect_rule1, conformTo_rule1, "No spaces are allowed behind the line continuation symbol '\\'"),
329*4882a593Smuzhiyun    (respect_rule2, conformTo_rule2, "Tabs should not be used (use spaces instead)"),
330*4882a593Smuzhiyun    (respect_rule3, conformTo_rule3, "Comments inside bb files are allowed using the '#' character at the beginning of a line"),
331*4882a593Smuzhiyun    (respect_rule4, conformTo_rule4, "Use quotes on the right hand side of assignments FOO = \"BAR\""),
332*4882a593Smuzhiyun    (respect_rule5, conformTo_rule5, "The correct spacing for a variable is FOO = \"BAR\""),
333*4882a593Smuzhiyun    (respect_rule6, conformTo_rule6, "Don't use spaces or tabs on empty lines"),
334*4882a593Smuzhiyun    (respect_rule7, conformTo_rule7, "Indentation of multiline variables such as SRC_URI is desireable"),
335*4882a593Smuzhiyun)
336*4882a593Smuzhiyun
337*4882a593Smuzhiyun# Function to check that a line respects a rule. If not, it tries to conform
338*4882a593Smuzhiyun# the line to the rule. Reminder or Disgression message are dump accordingly.
339*4882a593Smuzhiyun
340*4882a593Smuzhiyun
341*4882a593Smuzhiyundef follow_rule(i, line):
342*4882a593Smuzhiyun    oldline = line
343*4882a593Smuzhiyun    # if the line does not respect the rule
344*4882a593Smuzhiyun    if not rules[i][0](line):
345*4882a593Smuzhiyun        # try to conform it to the rule
346*4882a593Smuzhiyun        line = rules[i][1](line)
347*4882a593Smuzhiyun        # if the line still does not respect the rule
348*4882a593Smuzhiyun        if not rules[i][0](line):
349*4882a593Smuzhiyun            # this is a rule disgression
350*4882a593Smuzhiyun            print("## Disgression: ", rules[i][2], " in: '", oldline, "'")
351*4882a593Smuzhiyun        else:
352*4882a593Smuzhiyun            # just remind user about his/her errors
353*4882a593Smuzhiyun            print("## Reminder: ", rules[i][2], " in : '", oldline, "'")
354*4882a593Smuzhiyun    return line
355*4882a593Smuzhiyun
356*4882a593Smuzhiyun
357*4882a593Smuzhiyunif __name__ == "__main__":
358*4882a593Smuzhiyun
359*4882a593Smuzhiyun    # -- retrieves the lines of the .bb file --
360*4882a593Smuzhiyun    lines = []
361*4882a593Smuzhiyun    for line in fileinput.input():
362*4882a593Smuzhiyun        # use 'if True' to warn user about all the rule he/she breaks
363*4882a593Smuzhiyun        # use 'if False' to conform to rules{2,1,6} without warnings
364*4882a593Smuzhiyun        if True:
365*4882a593Smuzhiyun            lines.append(line)
366*4882a593Smuzhiyun        else:
367*4882a593Smuzhiyun            # expandtabs on each line so that rule2 is always respected
368*4882a593Smuzhiyun            # rstrip each line so that rule1 is always respected
369*4882a593Smuzhiyun            line = line.expandtabs().rstrip()
370*4882a593Smuzhiyun            # ignore empty lines (or line filled with spaces or tabs only)
371*4882a593Smuzhiyun            # so that rule6 is always respected
372*4882a593Smuzhiyun            if line != '':
373*4882a593Smuzhiyun                lines.append(line)
374*4882a593Smuzhiyun
375*4882a593Smuzhiyun    # -- parse the file --
376*4882a593Smuzhiyun    var = ""
377*4882a593Smuzhiyun    in_routine = False
378*4882a593Smuzhiyun    commentBloc = []
379*4882a593Smuzhiyun    olines = []
380*4882a593Smuzhiyun    for line in lines:
381*4882a593Smuzhiyun        originalLine = line
382*4882a593Smuzhiyun        # rstrip line to remove line breaks characters
383*4882a593Smuzhiyun        line = line.rstrip()
384*4882a593Smuzhiyun        line = follow_rule(2, line)
385*4882a593Smuzhiyun        line = follow_rule(1, line)
386*4882a593Smuzhiyun        line = follow_rule(6, line)
387*4882a593Smuzhiyun
388*4882a593Smuzhiyun        # ignore empty lines
389*4882a593Smuzhiyun        if line.isspace() or line == '':
390*4882a593Smuzhiyun            # flush comments into the olines
391*4882a593Smuzhiyun            for c in commentBloc:
392*4882a593Smuzhiyun                olines.append(c)
393*4882a593Smuzhiyun            commentBloc = []
394*4882a593Smuzhiyun            continue
395*4882a593Smuzhiyun
396*4882a593Smuzhiyun        if line.startswith('}'):
397*4882a593Smuzhiyun            in_routine = False
398*4882a593Smuzhiyun        keep = line.endswith('\\') or in_routine
399*4882a593Smuzhiyun
400*4882a593Smuzhiyun        # handles commented lines
401*4882a593Smuzhiyun        if line.lstrip().startswith('#'):
402*4882a593Smuzhiyun            # check and follow rule3 if not in a variables or routines
403*4882a593Smuzhiyun            if not in_routine:
404*4882a593Smuzhiyun                line = follow_rule(3, line)
405*4882a593Smuzhiyun            commentBloc.append(line)
406*4882a593Smuzhiyun            continue
407*4882a593Smuzhiyun
408*4882a593Smuzhiyun        if var in seen_vars:
409*4882a593Smuzhiyun            for c in commentBloc:
410*4882a593Smuzhiyun                seen_vars[var].append(c)
411*4882a593Smuzhiyun            commentBloc = []
412*4882a593Smuzhiyun            seen_vars[var].append(line)
413*4882a593Smuzhiyun        else:
414*4882a593Smuzhiyun            for k in OE_vars:
415*4882a593Smuzhiyun                if line.startswith(k):
416*4882a593Smuzhiyun                    var = k
417*4882a593Smuzhiyun                    break
418*4882a593Smuzhiyun            if re.match(routineRegexp, line) is not None:
419*4882a593Smuzhiyun                in_routine = True
420*4882a593Smuzhiyun                line = follow_rule(0, line)
421*4882a593Smuzhiyun            elif re.match(varRegexp, line) is not None:
422*4882a593Smuzhiyun                line = follow_rule(0, line)
423*4882a593Smuzhiyun                line = follow_rule(4, line)
424*4882a593Smuzhiyun                line = follow_rule(5, line)
425*4882a593Smuzhiyun            if var == "":
426*4882a593Smuzhiyun                if not in_routine:
427*4882a593Smuzhiyun                    print("## Warning: unknown variable/routine \"%s\"" % originalLine.rstrip('\n'))
428*4882a593Smuzhiyun                var = 'others'
429*4882a593Smuzhiyun            for c in commentBloc:
430*4882a593Smuzhiyun                seen_vars[var].append(c)
431*4882a593Smuzhiyun            commentBloc = []
432*4882a593Smuzhiyun            seen_vars[var].append(line)
433*4882a593Smuzhiyun        if not keep and not in_routine:
434*4882a593Smuzhiyun            var = ""
435*4882a593Smuzhiyun
436*4882a593Smuzhiyun    # -- dump the sanitized .bb file --
437*4882a593Smuzhiyun    addEmptyLine = False
438*4882a593Smuzhiyun    # write comments that are not related to variables nor routines
439*4882a593Smuzhiyun    for l in commentBloc:
440*4882a593Smuzhiyun        olines.append(l)
441*4882a593Smuzhiyun    # write variables and routines
442*4882a593Smuzhiyun    previourVarPrefix = "unknown"
443*4882a593Smuzhiyun    for k in OE_vars:
444*4882a593Smuzhiyun        if k == 'SRC_URI':
445*4882a593Smuzhiyun            addEmptyLine = True
446*4882a593Smuzhiyun        if seen_vars[k] != []:
447*4882a593Smuzhiyun            if addEmptyLine and not k.startswith(previourVarPrefix):
448*4882a593Smuzhiyun                olines.append("")
449*4882a593Smuzhiyun            for l in seen_vars[k]:
450*4882a593Smuzhiyun                olines.append(l)
451*4882a593Smuzhiyun            previourVarPrefix = k.split('_')[0] == '' and "unknown" or k.split('_')[0]
452*4882a593Smuzhiyun    for line in olines:
453*4882a593Smuzhiyun        print(line)
454