2016-08-05 22:07:41 +03:00
#!/usr/bin/python3
tests: add python parser for hwdb grammar
This works for hwdb/[67]0-*.hwdb. I also added code to parse hwdb/20-*, but those
files are huge, and parsing them using this parser is annoyingly slow (about one
minute for the biggest files). So I removed the support for hwdb/20-*, a much simpler
hand-generated parser should suffice for those.
Current output:
hwdb/60-evdev.hwdb: 24 match groups, 35 matches, 88 properties, 0.19323015213012695s to parse
Match 'evdev:input:b0003v05ACp0259*' is duplicated
Match 'evdev:input:b0003v05ACp025A*' is duplicated
Match 'evdev:input:b0003v05ACp025B*' is duplicated
hwdb/60-keyboard.hwdb: 122 match groups, 188 matches, 638 properties, 1.0906572341918945s to parse
Failed to parse: 'KEYBOARD_KEY_8F=switchvideomode'
Failed to parse: 'KEYBOARD_KEY_C0183=media'
Failed to parse: 'KEYBOARD_KEY_C0201=new'
Failed to parse: 'KEYBOARD_KEY_C0289=reply'
Failed to parse: 'KEYBOARD_KEY_C028B=forwardmail'
Failed to parse: 'KEYBOARD_KEY_C028C=send'
Failed to parse: 'KEYBOARD_KEY_C021A=undo'
Failed to parse: 'KEYBOARD_KEY_C0279=redo'
Failed to parse: 'KEYBOARD_KEY_C0208=print'
Failed to parse: 'KEYBOARD_KEY_C0207=save'
Failed to parse: 'KEYBOARD_KEY_C0194=file'
Failed to parse: 'KEYBOARD_KEY_C01A7=documents'
Failed to parse: 'KEYBOARD_KEY_C01B6=images'
Failed to parse: 'KEYBOARD_KEY_C01B7=sound'
Property KEYBOARD_KEY_c7 is duplicated
Failed to parse: 'KEYBOARD_KEY_cF=end'
hwdb/70-mouse.hwdb: 62 match groups, 93 matches, 68 properties, 0.34186625480651855s to parse
Match 'mouse:usb:v046dpc51b:name:Logitech USB Receiver:' is duplicated
hwdb/70-pointingstick.hwdb: 5 match groups, 14 matches, 7 properties, 0.06518816947937012s to parse
hwdb/70-touchpad.hwdb: 3 match groups, 5 matches, 3 properties, 0.039690494537353516s to parse
Subsequest commits will clean those issues up.
2016-08-05 17:53:06 +03:00
# -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
#
# This file is part of systemd.
#
# Copyright 2016 Zbigniew Jędrzejewski-Szmek
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# systemd is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with systemd; If not, see <http://www.gnu.org/licenses/>.
import functools
2016-08-05 22:07:41 +03:00
import glob
import string
import sys
import os
tests: add python parser for hwdb grammar
This works for hwdb/[67]0-*.hwdb. I also added code to parse hwdb/20-*, but those
files are huge, and parsing them using this parser is annoyingly slow (about one
minute for the biggest files). So I removed the support for hwdb/20-*, a much simpler
hand-generated parser should suffice for those.
Current output:
hwdb/60-evdev.hwdb: 24 match groups, 35 matches, 88 properties, 0.19323015213012695s to parse
Match 'evdev:input:b0003v05ACp0259*' is duplicated
Match 'evdev:input:b0003v05ACp025A*' is duplicated
Match 'evdev:input:b0003v05ACp025B*' is duplicated
hwdb/60-keyboard.hwdb: 122 match groups, 188 matches, 638 properties, 1.0906572341918945s to parse
Failed to parse: 'KEYBOARD_KEY_8F=switchvideomode'
Failed to parse: 'KEYBOARD_KEY_C0183=media'
Failed to parse: 'KEYBOARD_KEY_C0201=new'
Failed to parse: 'KEYBOARD_KEY_C0289=reply'
Failed to parse: 'KEYBOARD_KEY_C028B=forwardmail'
Failed to parse: 'KEYBOARD_KEY_C028C=send'
Failed to parse: 'KEYBOARD_KEY_C021A=undo'
Failed to parse: 'KEYBOARD_KEY_C0279=redo'
Failed to parse: 'KEYBOARD_KEY_C0208=print'
Failed to parse: 'KEYBOARD_KEY_C0207=save'
Failed to parse: 'KEYBOARD_KEY_C0194=file'
Failed to parse: 'KEYBOARD_KEY_C01A7=documents'
Failed to parse: 'KEYBOARD_KEY_C01B6=images'
Failed to parse: 'KEYBOARD_KEY_C01B7=sound'
Property KEYBOARD_KEY_c7 is duplicated
Failed to parse: 'KEYBOARD_KEY_cF=end'
hwdb/70-mouse.hwdb: 62 match groups, 93 matches, 68 properties, 0.34186625480651855s to parse
Match 'mouse:usb:v046dpc51b:name:Logitech USB Receiver:' is duplicated
hwdb/70-pointingstick.hwdb: 5 match groups, 14 matches, 7 properties, 0.06518816947937012s to parse
hwdb/70-touchpad.hwdb: 3 match groups, 5 matches, 3 properties, 0.039690494537353516s to parse
Subsequest commits will clean those issues up.
2016-08-05 17:53:06 +03:00
try :
from pyparsing import ( Word , White , Literal , ParserElement , Regex ,
LineStart , LineEnd ,
ZeroOrMore , OneOrMore , Combine , Or , Optional , Suppress , Group ,
nums , alphanums , printables ,
stringEnd , pythonStyleComment ,
ParseBaseException )
except ImportError :
2016-08-05 22:07:41 +03:00
print ( ' pyparsing is not available ' )
sys . exit ( 77 )
tests: add python parser for hwdb grammar
This works for hwdb/[67]0-*.hwdb. I also added code to parse hwdb/20-*, but those
files are huge, and parsing them using this parser is annoyingly slow (about one
minute for the biggest files). So I removed the support for hwdb/20-*, a much simpler
hand-generated parser should suffice for those.
Current output:
hwdb/60-evdev.hwdb: 24 match groups, 35 matches, 88 properties, 0.19323015213012695s to parse
Match 'evdev:input:b0003v05ACp0259*' is duplicated
Match 'evdev:input:b0003v05ACp025A*' is duplicated
Match 'evdev:input:b0003v05ACp025B*' is duplicated
hwdb/60-keyboard.hwdb: 122 match groups, 188 matches, 638 properties, 1.0906572341918945s to parse
Failed to parse: 'KEYBOARD_KEY_8F=switchvideomode'
Failed to parse: 'KEYBOARD_KEY_C0183=media'
Failed to parse: 'KEYBOARD_KEY_C0201=new'
Failed to parse: 'KEYBOARD_KEY_C0289=reply'
Failed to parse: 'KEYBOARD_KEY_C028B=forwardmail'
Failed to parse: 'KEYBOARD_KEY_C028C=send'
Failed to parse: 'KEYBOARD_KEY_C021A=undo'
Failed to parse: 'KEYBOARD_KEY_C0279=redo'
Failed to parse: 'KEYBOARD_KEY_C0208=print'
Failed to parse: 'KEYBOARD_KEY_C0207=save'
Failed to parse: 'KEYBOARD_KEY_C0194=file'
Failed to parse: 'KEYBOARD_KEY_C01A7=documents'
Failed to parse: 'KEYBOARD_KEY_C01B6=images'
Failed to parse: 'KEYBOARD_KEY_C01B7=sound'
Property KEYBOARD_KEY_c7 is duplicated
Failed to parse: 'KEYBOARD_KEY_cF=end'
hwdb/70-mouse.hwdb: 62 match groups, 93 matches, 68 properties, 0.34186625480651855s to parse
Match 'mouse:usb:v046dpc51b:name:Logitech USB Receiver:' is duplicated
hwdb/70-pointingstick.hwdb: 5 match groups, 14 matches, 7 properties, 0.06518816947937012s to parse
hwdb/70-touchpad.hwdb: 3 match groups, 5 matches, 3 properties, 0.039690494537353516s to parse
Subsequest commits will clean those issues up.
2016-08-05 17:53:06 +03:00
try :
from evdev . ecodes import ecodes
except ImportError :
ecodes = None
print ( ' WARNING: evdev is not available ' )
EOL = LineEnd ( ) . suppress ( )
EMPTYLINE = LineStart ( ) + LineEnd ( )
COMMENTLINE = pythonStyleComment + EOL
INTEGER = Word ( nums )
REAL = Combine ( ( INTEGER + Optional ( ' . ' + Optional ( INTEGER ) ) ) ^ ( ' . ' + INTEGER ) )
UDEV_TAG = Word ( string . ascii_uppercase , alphanums + ' _ ' )
TYPES = { ' mouse ' : ( ' usb ' , ' bluetooth ' , ' ps2 ' , ' * ' ) ,
' evdev ' : ( ' name ' , ' atkbd ' , ' input ' ) ,
' touchpad ' : ( ' i8042 ' , ' rmi ' , ' bluetooth ' , ' usb ' ) ,
' keyboard ' : ( ' name ' , ) ,
}
@functools.lru_cache ( )
def hwdb_grammar ( ) :
ParserElement . setDefaultWhitespaceChars ( ' ' )
prefix = Or ( category + ' : ' + Or ( conn ) + ' : '
for category , conn in TYPES . items ( ) )
matchline = Combine ( prefix + Word ( printables + ' ' + ' ® ' ) ) + EOL
propertyline = ( White ( ' ' , exact = 1 ) . suppress ( ) +
Combine ( UDEV_TAG - ' = ' - Word ( alphanums + ' _=:@*.! ' ) - Optional ( pythonStyleComment ) ) +
EOL )
propertycomment = White ( ' ' , exact = 1 ) + pythonStyleComment + EOL
group = ( OneOrMore ( matchline ( ' MATCHES* ' ) ^ COMMENTLINE . suppress ( ) ) -
OneOrMore ( propertyline ( ' PROPERTIES* ' ) ^ propertycomment . suppress ( ) ) -
( EMPTYLINE ^ stringEnd ( ) ) . suppress ( ) )
commentgroup = OneOrMore ( COMMENTLINE ) . suppress ( ) - EMPTYLINE . suppress ( )
grammar = OneOrMore ( group ( ' GROUPS* ' ) ^ commentgroup ) + stringEnd ( )
return grammar
@functools.lru_cache ( )
def property_grammar ( ) :
ParserElement . setDefaultWhitespaceChars ( ' ' )
setting = Optional ( ' * ' ) ( ' DEFAULT ' ) + INTEGER ( ' DPI ' ) + Suppress ( ' @ ' ) + INTEGER ( ' HZ ' )
props = ( ( ' MOUSE_DPI ' , Group ( OneOrMore ( setting ( ' SETTINGS* ' ) ) ) ) ,
( ' MOUSE_WHEEL_CLICK_ANGLE ' , INTEGER ) ,
2016-08-19 16:31:36 +03:00
( ' MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL ' , INTEGER ) ,
tests: add python parser for hwdb grammar
This works for hwdb/[67]0-*.hwdb. I also added code to parse hwdb/20-*, but those
files are huge, and parsing them using this parser is annoyingly slow (about one
minute for the biggest files). So I removed the support for hwdb/20-*, a much simpler
hand-generated parser should suffice for those.
Current output:
hwdb/60-evdev.hwdb: 24 match groups, 35 matches, 88 properties, 0.19323015213012695s to parse
Match 'evdev:input:b0003v05ACp0259*' is duplicated
Match 'evdev:input:b0003v05ACp025A*' is duplicated
Match 'evdev:input:b0003v05ACp025B*' is duplicated
hwdb/60-keyboard.hwdb: 122 match groups, 188 matches, 638 properties, 1.0906572341918945s to parse
Failed to parse: 'KEYBOARD_KEY_8F=switchvideomode'
Failed to parse: 'KEYBOARD_KEY_C0183=media'
Failed to parse: 'KEYBOARD_KEY_C0201=new'
Failed to parse: 'KEYBOARD_KEY_C0289=reply'
Failed to parse: 'KEYBOARD_KEY_C028B=forwardmail'
Failed to parse: 'KEYBOARD_KEY_C028C=send'
Failed to parse: 'KEYBOARD_KEY_C021A=undo'
Failed to parse: 'KEYBOARD_KEY_C0279=redo'
Failed to parse: 'KEYBOARD_KEY_C0208=print'
Failed to parse: 'KEYBOARD_KEY_C0207=save'
Failed to parse: 'KEYBOARD_KEY_C0194=file'
Failed to parse: 'KEYBOARD_KEY_C01A7=documents'
Failed to parse: 'KEYBOARD_KEY_C01B6=images'
Failed to parse: 'KEYBOARD_KEY_C01B7=sound'
Property KEYBOARD_KEY_c7 is duplicated
Failed to parse: 'KEYBOARD_KEY_cF=end'
hwdb/70-mouse.hwdb: 62 match groups, 93 matches, 68 properties, 0.34186625480651855s to parse
Match 'mouse:usb:v046dpc51b:name:Logitech USB Receiver:' is duplicated
hwdb/70-pointingstick.hwdb: 5 match groups, 14 matches, 7 properties, 0.06518816947937012s to parse
hwdb/70-touchpad.hwdb: 3 match groups, 5 matches, 3 properties, 0.039690494537353516s to parse
Subsequest commits will clean those issues up.
2016-08-05 17:53:06 +03:00
( ' ID_INPUT_TRACKBALL ' , Literal ( ' 1 ' ) ) ,
( ' POINTINGSTICK_SENSITIVITY ' , INTEGER ) ,
( ' POINTINGSTICK_CONST_ACCEL ' , REAL ) ,
( ' ID_INPUT_TOUCHPAD_INTEGRATION ' , Or ( ( ' internal ' , ' external ' ) ) ) ,
)
fixed_props = [ Literal ( name ) ( ' NAME ' ) - Suppress ( ' = ' ) - val ( ' VALUE ' )
for name , val in props ]
kbd_props = [ Regex ( r ' KEYBOARD_KEY_[0-9a-f]+ ' ) ( ' NAME ' )
- Suppress ( ' = ' ) -
( ' ! ' ^ ( Optional ( ' ! ' ) - Word ( alphanums + ' _ ' ) ) ) ( ' VALUE ' )
]
abs_props = [ Regex ( r ' EVDEV_ABS_[0-9a-f] {2} ' ) ( ' NAME ' )
- Suppress ( ' = ' ) -
Word ( nums + ' : ' ) ( ' VALUE ' )
]
grammar = Or ( fixed_props + kbd_props + abs_props )
return grammar
ERROR = False
def error ( fmt , * args , * * kwargs ) :
global ERROR
ERROR = True
print ( fmt . format ( * args , * * kwargs ) )
def convert_properties ( group ) :
matches = [ m [ 0 ] for m in group . MATCHES ]
props = [ p [ 0 ] for p in group . PROPERTIES ]
return matches , props
def parse ( fname ) :
grammar = hwdb_grammar ( )
try :
parsed = grammar . parseFile ( fname )
except ParseBaseException as e :
error ( ' Cannot parse {} : {} ' , fname , e )
return [ ]
return [ convert_properties ( g ) for g in parsed . GROUPS ]
def check_match_uniqueness ( groups ) :
matches = sum ( ( group [ 0 ] for group in groups ) , [ ] )
matches . sort ( )
prev = None
for match in matches :
if match == prev :
error ( ' Match {!r} is duplicated ' , match )
prev = match
def check_one_default ( prop , settings ) :
defaults = [ s for s in settings if s . DEFAULT ]
if len ( defaults ) > 1 :
error ( ' More than one star entry: {!r} ' , prop )
def check_one_keycode ( prop , value ) :
if value != ' ! ' and ecodes is not None :
key = ' KEY_ ' + value . upper ( )
if key not in ecodes :
error ( ' Keycode {} unknown ' , key )
def check_properties ( groups ) :
grammar = property_grammar ( )
for matches , props in groups :
prop_names = set ( )
for prop in props :
# print('--', prop)
prop = prop . partition ( ' # ' ) [ 0 ] . rstrip ( )
try :
parsed = grammar . parseString ( prop )
except ParseBaseException as e :
error ( ' Failed to parse: {!r} ' , prop )
continue
# print('{!r}'.format(parsed))
if parsed . NAME in prop_names :
error ( ' Property {} is duplicated ' , parsed . NAME )
prop_names . add ( parsed . NAME )
if parsed . NAME == ' MOUSE_DPI ' :
check_one_default ( prop , parsed . VALUE . SETTINGS )
elif parsed . NAME . startswith ( ' KEYBOARD_KEY_ ' ) :
check_one_keycode ( prop , parsed . VALUE )
def print_summary ( fname , groups ) :
print ( ' {} : {} match groups, {} matches, {} properties '
. format ( fname ,
len ( groups ) ,
sum ( len ( matches ) for matches , props in groups ) ,
sum ( len ( props ) for matches , props in groups ) ,
) )
if __name__ == ' __main__ ' :
2016-08-05 22:07:41 +03:00
args = sys . argv [ 1 : ] or glob . glob ( os . path . dirname ( sys . argv [ 0 ] ) + ' /[67]0-*.hwdb ' )
for fname in args :
tests: add python parser for hwdb grammar
This works for hwdb/[67]0-*.hwdb. I also added code to parse hwdb/20-*, but those
files are huge, and parsing them using this parser is annoyingly slow (about one
minute for the biggest files). So I removed the support for hwdb/20-*, a much simpler
hand-generated parser should suffice for those.
Current output:
hwdb/60-evdev.hwdb: 24 match groups, 35 matches, 88 properties, 0.19323015213012695s to parse
Match 'evdev:input:b0003v05ACp0259*' is duplicated
Match 'evdev:input:b0003v05ACp025A*' is duplicated
Match 'evdev:input:b0003v05ACp025B*' is duplicated
hwdb/60-keyboard.hwdb: 122 match groups, 188 matches, 638 properties, 1.0906572341918945s to parse
Failed to parse: 'KEYBOARD_KEY_8F=switchvideomode'
Failed to parse: 'KEYBOARD_KEY_C0183=media'
Failed to parse: 'KEYBOARD_KEY_C0201=new'
Failed to parse: 'KEYBOARD_KEY_C0289=reply'
Failed to parse: 'KEYBOARD_KEY_C028B=forwardmail'
Failed to parse: 'KEYBOARD_KEY_C028C=send'
Failed to parse: 'KEYBOARD_KEY_C021A=undo'
Failed to parse: 'KEYBOARD_KEY_C0279=redo'
Failed to parse: 'KEYBOARD_KEY_C0208=print'
Failed to parse: 'KEYBOARD_KEY_C0207=save'
Failed to parse: 'KEYBOARD_KEY_C0194=file'
Failed to parse: 'KEYBOARD_KEY_C01A7=documents'
Failed to parse: 'KEYBOARD_KEY_C01B6=images'
Failed to parse: 'KEYBOARD_KEY_C01B7=sound'
Property KEYBOARD_KEY_c7 is duplicated
Failed to parse: 'KEYBOARD_KEY_cF=end'
hwdb/70-mouse.hwdb: 62 match groups, 93 matches, 68 properties, 0.34186625480651855s to parse
Match 'mouse:usb:v046dpc51b:name:Logitech USB Receiver:' is duplicated
hwdb/70-pointingstick.hwdb: 5 match groups, 14 matches, 7 properties, 0.06518816947937012s to parse
hwdb/70-touchpad.hwdb: 3 match groups, 5 matches, 3 properties, 0.039690494537353516s to parse
Subsequest commits will clean those issues up.
2016-08-05 17:53:06 +03:00
groups = parse ( fname )
print_summary ( fname , groups )
check_match_uniqueness ( groups )
check_properties ( groups )
sys . exit ( ERROR )