1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
#!/bin/bash
# This command imports the native HAL video quirks into the pm-utils native
# format. It knows just enough about the video quirk .fdi files to translate
# them into a format that bash can more easily parse.
# While we are at it, replace the .fdi ad-hoc pattern matching language with
# extended regular expressions where we can.
# If anyone wants fo rewrite this in a language that actually understands
# XML, feel free.
# If run with no arguments, it will translate the already installed .fdi
# quirks into the native ones at their default location.
# If run with one argument, it will translate the .fdi quirks located at
# $1 into the native ones at their default location.
# if run with two arguments, it will translate the .fdi quirks located at $1
# into the native ones at $2.
. "@PM-UTILS-LIBDIR@/pm-functions"
shopt -s extglob
begin_match='<match key="([a-z._]+)" ([a-z_]+)="([^"]+)">'
end_match='</match>'
merge='<merge key="([^"]+)" type="bool">true</merge>'
remove='<remove key="([^"]+)"></remove>'
begin_comment='<!--'
end_comment='-->'
in_comment=0
in_match=0
# test to see if the parameter passed is a decimal or hexidecimal number
# Note the complete lack of floating point support.
isnum() {
[[ $1 =~ ^[0-9]+\$ || $1 =~ ^0[xX][0-9a-fA-F]+\$ ]]
}
space_echo() {
for ((i=$1; i>0; i--)); do
printf ' '
done
shift
echo "$1"
}
# Helper function for when translating from .fdi to native format,
# we need to massage things a little.
escape_match() {
local fun lit
fun="regex"
# first, escape special ere characters
lit="$2"
lit="${lit//\\/\\\\}"
lit="${lit//./\\.}"
lit="${lit//^/\\^}"
lit="${lit//[/\\\[}"
lit="${lit//]/\\\]}"
lit="${lit//(/\\\(}"
lit="${lit//)/\\\)}"
lit="${lit//\*/\\\*}"
lit="${lit//\+/\\\+}"
lit="${lit//\?/\\\?}"
lit="${lit//\{/\\\{}"
lit="${lit//\}/\\\}}"
lit="${lit//\|/\\\|}"
lit="${lit//\$/\\\$}"
# nuke leading and trailing spaces, they just confuse things.
lit="${lit%%+( )}"
lit="${lit##+( )}"
# second, handle the various comparison cases, munging them into
# extended regular expressions that bash understands.
case $1 in
string) lit="^${lit}\$" ;;
int|uint64) fun=numeric_compare_eq ;;
string_outof) lit="${lit%;}"; lit="^(${lit/(*( );*( )/|})\$" ;;
int_outof) fun=numeric_compare_eq_list ;;
contains) ;;
contains_outof) lit="${lit%;}"; lit="${lit//*( );*( )/|}" ;;
prefix) lit="^${lit}" ;;
prefix_outof) lit="${lit%;}"; lit="^(${lit//*( );*( )/|})" ;;
suffix) lit="${lit}\$" ;;
contains_ncase) fun=regex_ncase ;;
contains_not) fun=regex_inverse ;;
prefix_ncase) fun=regex_ncase; lit="^${lit}" ;;
suffix_ncase) fun=regex_ncase; lit="${lit}\$" ;;
compare_lt|compare_le|compare_gt|compare_ge|compare_ne)
# I know, this may not always be the right thing to do.
# It is the right thing most of the time, though.
if isnum "$lit"; then
fun="numeric_$1"
else
fun="$1"
fi
;;
*) echo "$1 not implemented." >&2 ; exit 1 ;;
esac
echo "$fun $lit"
}
# This is so not the right way to parse XML, but it happens to work with
# the current hal-info video quirk .fdi files. Maybe someday I will rewrite
# this in a language that actually understands XML, even though XML is the devil.
translate_xml() {
local line key val matcher in_comment in_matcher
while read line; do
[[ "$line" ]] || continue
if [[ $line =~ $begin_comment && $line =~ $end_comment ]]; then
space_echo $in_match "# $line"
elif [[ $line =~ $begin_comment ]]; then
space_echo $in_match "# $line"
((in_comment++))
elif [[ $line =~ $end_comment ]]; then
space_echo $in_match "# $line"
((in_comment--))
elif ((in_comment > 0)); then
space_echo $in_match "# $line"
elif [[ $line =~ $begin_match ]]; then
((in_match++))
key="${BASH_REMATCH[1]}"
matcher="${BASH_REMATCH[2]}"
val="${BASH_REMATCH[3]}"
space_echo $in_match "match $key $(escape_match "$matcher" "$val")"
elif [[ $line =~ $end_match ]]; then
space_echo $in_match "endmatch"
((in_match--))
elif [[ $line =~ $merge ]]; then
key="${BASH_REMATCH[1]##*.}"
space_echo $((in_match + 1)) "addquirk --quirk-${key//_/-}"
elif [[ $line =~ $remove ]]; then
key="${BASH_REMATCH[1]##*.}"
space_echo $((in_match + 1)) "delquirk --quirk-${key//_/-}"
fi
done
}
loc="/usr/share/hal/fdi/information/10freedesktop/20-video-quirk*.fdi"
[[ $1 && -d $1 ]] && loc="$1/20-video-quirk*.fdi"
[[ $2 ]] && PM_QUIRKDB="$2"
mkdir -p "$PM_QUIRKDB"
for f in $loc;
do
lf="$PM_QUIRKDB/${f##*/}"
lf="${lf%.*}.quirkdb"
[[ -f $f ]] || continue
[[ $f -nt $lf ]] || continue
translate_xml < "$f" > "$lf"
rm "$PM_LKW_QUIRKS" >/dev/null 2>&1
done
|