summaryrefslogtreecommitdiff
path: root/src/import-fdi-quirkdb.in
blob: 263c3be5f1a7198aa86cbf82214f4b25af3539fe (plain)
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