4 Sanitize a bitbake file following the OpenEmbedded style guidelines,
5 see http://openembedded.org/wiki/StyleGuide
7 (C) 2006 Cyril Romain <cyril.romain@gmail.com>
11 - add the others OpenEmbedded variables commonly used:
12 - parse command arguments and print usage on misuse
13 . prevent giving more than one .bb file in arguments
14 - write result to a file
15 - backup the original .bb file
16 - make a diff and ask confirmation for patching ?
17 - do not use startswith only:
18 /!\ startswith('SOMETHING') is not taken into account due to the previous startswith('S').
19 - count rule breaks and displays them in the order frequence
26 __author__
= "Cyril Romain <cyril.romain@gmail.com>"
27 __version__
= "$Revision: 0.5 $"
29 # The standard set of variables often found in .bb files in the preferred order
88 'ALTERNATIVE_PRIORITY',
92 'ANGSTROM_EXTRA_INSTALL',
101 'ARM_INSTRUCTION_SET',
114 'COLLIE_MEMORY_SIZE',
116 'COMPATIBLE_MACHINE',
128 'DEFAULT_PREFERENCE',
130 'EXCLUDE_FROM_SHLIBS',
131 'EXCLUDE_FROM_WORLD',
134 'GLIBC_EXTRA_OECONF',
137 'INHIBIT_DEFAULT_DEPS',
138 'INITSCRIPT_PACKAGES',
163 'MACHINE_ESSENTIAL_EXTRA_RDEPENDS',
164 'MACHINE_ESSENTIAL_EXTRA_RRECOMMENDS',
165 'MACHINE_EXTRA_RDEPENDS',
166 'MACHINE_EXTRA_RRECOMMENDS',
176 'OE_QMAKE_INCDIR_QT',
191 'ROOTFS_POSTPROCESS_COMMAND',
205 varRegexp
= r
'^([a-zA-Z_0-9${}-]*)([ \t]*)([+.:]?=[+.]?)([ \t]*)([^\t]+)'
206 routineRegexp
= r
'^([a-zA-Z0-9_ ${}-]+?)\('
208 # Variables seen in the processed .bb
213 # _Format guideline #0_:
214 # No spaces are allowed at the beginning of lines that define a variable or
216 def respect_rule0(line
):
217 return line
.lstrip()==line
218 def conformTo_rule0(line
):
221 # _Format guideline #1_:
222 # No spaces are allowed behind the line continuation symbol '\'
223 def respect_rule1(line
):
224 if line
.rstrip().endswith('\\'):
225 return line
.endswith('\\')
228 def conformTo_rule1(line
):
231 # _Format guideline #2_:
232 # Tabs should not be used (use spaces instead).
233 def respect_rule2(line
):
234 return line
.count('\t')==0
235 def conformTo_rule2(line
):
236 return line
.expandtabs()
238 # _Format guideline #3_:
239 # Comments inside bb files are allowed using the '#' character at the
240 # beginning of a line.
241 def respect_rule3(line
):
242 if line
.lstrip().startswith('#'):
243 return line
.startswith('#')
246 def conformTo_rule3(line
):
249 # _Format guideline #4_:
250 # Use quotes on the right hand side of assignments FOO = "BAR"
251 def respect_rule4(line
):
252 r
= re
.search(varRegexp
, line
)
254 r2
= re
.search(r
'("?)([^"\\]*)(["\\]?)', r
.group(5))
255 # do not test for None it because always match
256 return r2
.group(1)=='"' and r2
.group(3)!=''
258 def conformTo_rule4(line
):
259 r
= re
.search(varRegexp
, line
)
260 return ''.join([r
.group(1), ' ', r
.group(3), ' "', r
.group(5), r
.group(5).endswith('"') and '' or '"'])
262 # _Format guideline #5_:
263 # The correct spacing for a variable is FOO = "BAR".
264 def respect_rule5(line
):
265 r
= re
.search(varRegexp
, line
)
266 return r
is not None and r
.group(2)==" " and r
.group(4)==" "
267 def conformTo_rule5(line
):
268 r
= re
.search(varRegexp
, line
)
269 return ''.join([r
.group(1), ' ', r
.group(3), ' ', r
.group(5)])
271 # _Format guideline #6_:
272 # Don't use spaces or tabs on empty lines
273 def respect_rule6(line
):
274 return not line
.isspace() or line
=="\n"
275 def conformTo_rule6(line
):
278 # _Format guideline #7_:
279 # Indentation of multiline variables such as SRC_URI is desireable.
280 def respect_rule7(line
):
282 def conformTo_rule7(line
):
286 (respect_rule0
, conformTo_rule0
, "No spaces are allowed at the beginning of lines that define a variable or a do_ routine"),
287 (respect_rule1
, conformTo_rule1
, "No spaces are allowed behind the line continuation symbol '\\'"),
288 (respect_rule2
, conformTo_rule2
, "Tabs should not be used (use spaces instead)"),
289 (respect_rule3
, conformTo_rule3
, "Comments inside bb files are allowed using the '#' character at the beginning of a line"),
290 (respect_rule4
, conformTo_rule4
, "Use quotes on the right hand side of assignments FOO = \"BAR\""),
291 (respect_rule5
, conformTo_rule5
, "The correct spacing for a variable is FOO = \"BAR\""),
292 (respect_rule6
, conformTo_rule6
, "Don't use spaces or tabs on empty lines"),
293 (respect_rule7
, conformTo_rule7
, "Indentation of multiline variables such as SRC_URI is desireable"),
296 # Function to check that a line respects a rule. If not, it tries to conform
297 # the line to the rule. Reminder or Disgression message are dump accordingly.
298 def follow_rule(i
, line
):
300 # if the line does not respect the rule
301 if not rules
[i
][0](line
):
302 # try to conform it to the rule
303 line
= rules
[i
][1](line
)
304 # if the line still does not respect the rule
305 if not rules
[i
][0](line
):
306 # this is a rule disgression
307 print "## Disgression: ", rules
[i
][2], " in:", oldline
309 # just remind user about his/her errors
310 print "## Reminder: ", rules
[i
][2], " in :", oldline
314 if __name__
== "__main__":
316 # -- retrieves the lines of the .bb file --
318 for line
in fileinput
.input():
319 # use 'if True' to warn user about all the rule he/she breaks
320 # use 'if False' to conform to rules{2,1,6} without warnings
324 # expandtabs on each line so that rule2 is always respected
325 # rstrip each line so that rule1 is always respected
326 line
= line
.expandtabs().rstrip()
327 # ignore empty lines (or line filled with spaces or tabs only)
328 # so that rule6 is always respected
332 # -- parse the file --
339 # rstrip line to remove line breaks characters
341 line
= follow_rule(2, line
)
342 line
= follow_rule(1, line
)
343 line
= follow_rule(6, line
)
346 if line
.isspace() or line
is '':
347 # flush comments into the olines
348 for c
in commentBloc
: olines
.append(c
)
352 if line
.startswith('}'):
354 keep
= line
.endswith('\\') or in_routine
356 # handles commented lines
357 if line
.lstrip().startswith('#'):
358 # check and follow rule3 if not in a variables or routines
360 line
= follow_rule(3, line
)
361 commentBloc
.append(line
)
364 if seen_vars
.has_key(var
):
365 for c
in commentBloc
: seen_vars
[var
].append(c
)
367 seen_vars
[var
].append(line
)
370 if line
.startswith(k
):
373 if re
.match(routineRegexp
, line
) is not None:
375 line
= follow_rule(0, line
)
376 elif re
.match(varRegexp
, line
) is not None:
377 line
= follow_rule(0, line
)
378 line
= follow_rule(4, line
)
379 line
= follow_rule(5, line
)
382 print "## Warning: unknown variable/routine \"%s\"" % originalLine
384 for c
in commentBloc
: seen_vars
[var
].append(c
)
386 seen_vars
[var
].append(line
)
387 if not keep
and not in_routine
: var
= ""
389 # -- dump the sanitized .bb file --
391 # write comments that are not related to variables nor routines
392 for l
in commentBloc
: olines
.append(l
)
393 # write variables and routines
394 previourVarPrefix
= "unknown"
396 if k
=='SRC_URI': addEmptyLine
= True
397 if seen_vars
[k
] != []:
398 if addEmptyLine
and not k
.startswith(previourVarPrefix
):
400 for l
in seen_vars
[k
]:
402 previourVarPrefix
= k
.split('_')[0]=='' and "unknown" or k
.split('_')[0]
403 for line
in olines
: print line