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
87 'ALTERNATIVE_PRIORITY',
91 'ANGSTROM_EXTRA_INSTALL',
100 'ARM_INSTRUCTION_SET',
113 'COLLIE_MEMORY_SIZE',
115 'COMPATIBLE_MACHINE',
127 'DEFAULT_PREFERENCE',
129 'EXCLUDE_FROM_SHLIBS',
130 'EXCLUDE_FROM_WORLD',
133 'GLIBC_EXTRA_OECONF',
136 'INHIBIT_DEFAULT_DEPS',
137 'INITSCRIPT_PACKAGES',
162 'MACHINE_ESSENTIAL_EXTRA_RDEPENDS',
163 'MACHINE_ESSENTIAL_EXTRA_RRECOMMENDS',
164 'MACHINE_EXTRA_RDEPENDS',
165 'MACHINE_EXTRA_RRECOMMENDS',
175 'OE_QMAKE_INCDIR_QT',
190 'ROOTFS_POSTPROCESS_COMMAND',
204 varRegexp
= r
'^([a-zA-Z_0-9${}-]*)([ \t]*)([+.:]?=[+.]?)([ \t]*)([^\t]+)'
205 routineRegexp
= r
'^([a-zA-Z0-9_ ${}-]+?)\('
207 # Variables seen in the processed .bb
212 # _Format guideline #0_:
213 # No spaces are allowed at the beginning of lines that define a variable or
215 def respect_rule0(line
):
216 return line
.lstrip()==line
217 def conformTo_rule0(line
):
220 # _Format guideline #1_:
221 # No spaces are allowed behind the line continuation symbol '\'
222 def respect_rule1(line
):
223 if line
.rstrip().endswith('\\'):
224 return line
.endswith('\\')
227 def conformTo_rule1(line
):
230 # _Format guideline #2_:
231 # Tabs should not be used (use spaces instead).
232 def respect_rule2(line
):
233 return line
.count('\t')==0
234 def conformTo_rule2(line
):
235 return line
.expandtabs()
237 # _Format guideline #3_:
238 # Comments inside bb files are allowed using the '#' character at the
239 # beginning of a line.
240 def respect_rule3(line
):
241 if line
.lstrip().startswith('#'):
242 return line
.startswith('#')
245 def conformTo_rule3(line
):
248 # _Format guideline #4_:
249 # Use quotes on the right hand side of assignments FOO = "BAR"
250 def respect_rule4(line
):
251 r
= re
.search(varRegexp
, line
)
253 r2
= re
.search(r
'("?)([^"\\]*)(["\\]?)', r
.group(5))
254 # do not test for None it because always match
255 return r2
.group(1)=='"' and r2
.group(3)!=''
257 def conformTo_rule4(line
):
258 r
= re
.search(varRegexp
, line
)
259 return ''.join([r
.group(1), ' ', r
.group(3), ' "', r
.group(5), r
.group(5).endswith('"') and '' or '"'])
261 # _Format guideline #5_:
262 # The correct spacing for a variable is FOO = "BAR".
263 def respect_rule5(line
):
264 r
= re
.search(varRegexp
, line
)
265 return r
is not None and r
.group(2)==" " and r
.group(4)==" "
266 def conformTo_rule5(line
):
267 r
= re
.search(varRegexp
, line
)
268 return ''.join([r
.group(1), ' ', r
.group(3), ' ', r
.group(5)])
270 # _Format guideline #6_:
271 # Don't use spaces or tabs on empty lines
272 def respect_rule6(line
):
273 return not line
.isspace() or line
=="\n"
274 def conformTo_rule6(line
):
277 # _Format guideline #7_:
278 # Indentation of multiline variables such as SRC_URI is desireable.
279 def respect_rule7(line
):
281 def conformTo_rule7(line
):
285 (respect_rule0
, conformTo_rule0
, "No spaces are allowed at the beginning of lines that define a variable or a do_ routine"),
286 (respect_rule1
, conformTo_rule1
, "No spaces are allowed behind the line continuation symbol '\\'"),
287 (respect_rule2
, conformTo_rule2
, "Tabs should not be used (use spaces instead)"),
288 (respect_rule3
, conformTo_rule3
, "Comments inside bb files are allowed using the '#' character at the beginning of a line"),
289 (respect_rule4
, conformTo_rule4
, "Use quotes on the right hand side of assignments FOO = \"BAR\""),
290 (respect_rule5
, conformTo_rule5
, "The correct spacing for a variable is FOO = \"BAR\""),
291 (respect_rule6
, conformTo_rule6
, "Don't use spaces or tabs on empty lines"),
292 (respect_rule7
, conformTo_rule7
, "Indentation of multiline variables such as SRC_URI is desireable"),
295 # Function to check that a line respects a rule. If not, it tries to conform
296 # the line to the rule. Reminder or Disgression message are dump accordingly.
297 def follow_rule(i
, line
):
299 # if the line does not respect the rule
300 if not rules
[i
][0](line
):
301 # try to conform it to the rule
302 line
= rules
[i
][1](line
)
303 # if the line still does not respect the rule
304 if not rules
[i
][0](line
):
305 # this is a rule disgression
306 print "## Disgression: ", rules
[i
][2], " in:", oldline
308 # just remind user about his/her errors
309 print "## Reminder: ", rules
[i
][2], " in :", oldline
313 if __name__
== "__main__":
315 # -- retrieves the lines of the .bb file --
317 for line
in fileinput
.input():
318 # use 'if True' to warn user about all the rule he/she breaks
319 # use 'if False' to conform to rules{2,1,6} without warnings
323 # expandtabs on each line so that rule2 is always respected
324 # rstrip each line so that rule1 is always respected
325 line
= line
.expandtabs().rstrip()
326 # ignore empty lines (or line filled with spaces or tabs only)
327 # so that rule6 is always respected
331 # -- parse the file --
338 # rstrip line to remove line breaks characters
340 line
= follow_rule(2, line
)
341 line
= follow_rule(1, line
)
342 line
= follow_rule(6, line
)
345 if line
.isspace() or line
is '':
346 # flush comments into the olines
347 for c
in commentBloc
: olines
.append(c
)
351 if line
.startswith('}'):
353 keep
= line
.endswith('\\') or in_routine
355 # handles commented lines
356 if line
.lstrip().startswith('#'):
357 # check and follow rule3 if not in a variables or routines
359 line
= follow_rule(3, line
)
360 commentBloc
.append(line
)
363 if seen_vars
.has_key(var
):
364 for c
in commentBloc
: seen_vars
[var
].append(c
)
366 seen_vars
[var
].append(line
)
369 if line
.startswith(k
):
372 if re
.match(routineRegexp
, line
) is not None:
374 line
= follow_rule(0, line
)
375 elif re
.match(varRegexp
, line
) is not None:
376 line
= follow_rule(0, line
)
377 line
= follow_rule(4, line
)
378 line
= follow_rule(5, line
)
381 print "## Warning: unknown variable/routine \"%s\"" % originalLine
383 for c
in commentBloc
: seen_vars
[var
].append(c
)
385 seen_vars
[var
].append(line
)
386 if not keep
and not in_routine
: var
= ""
388 # -- dump the sanitized .bb file --
390 # write comments that are not related to variables nor routines
391 for l
in commentBloc
: olines
.append(l
)
392 # write variables and routines
393 previourVarPrefix
= "unknown"
395 if k
=='SRC_URI': addEmptyLine
= True
396 if seen_vars
[k
] != []:
397 if addEmptyLine
and not k
.startswith(previourVarPrefix
):
399 for l
in seen_vars
[k
]:
401 previourVarPrefix
= k
.split('_')[0]=='' and "unknown" or k
.split('_')[0]
402 for line
in olines
: print line