Showing 2 changed files with 319 additions and 98 deletions
+318 -96
.fgfs/fgaddon
... ...
@@ -1,30 +1,75 @@
1 1
 #!/bin/bash
2 2
 
3
+set -e
4
+
5
+declare -A data=(
6
+        [/sim/description]=text
7
+        [/sim/long-description]=text
8
+        [/sim/author]=text
9
+        [/sim/flight-model]=text
10
+        [/sim/type]=text
11
+        [/sim/model/path]=text
12
+)
3 13
 fgaddon_url=https://sourceforge.net/p/flightgear/fgaddon/HEAD/tree/trunk/Aircraft
4 14
 fgaddon_svn=https://svn.code.sf.net/p/flightgear/fgaddon/trunk/Aircraft
5 15
 fgaddon_path=$HOME/.fgfs/flightgear-fgaddon/Aircraft
16
+database=${DB:-$0.db}
17
+#locale=fr
18
+
19
+test -r "$0.conf" && source $0.conf && echo config red
20
+
6 21
 
7 22
 aircrafts=$(mktemp --dry-run /dev/shm/Aircraft-XXXXXXXXX)
8 23
 aircraft=$(mktemp --dry-run /dev/shm/aircraft-XXXXXXX)
9 24
 setxml=$(mktemp --dry-run /dev/shm/setxml-XXXXXXXX)
10 25
 in_ram_database=$(mktemp --dry-run /dev/shm/XXXXXXX)
11
-database=${DB:-$0.db}
12 26
 
13
-attributes=(description long-description author flight-model type)
14 27
 
15
-xmlgetnext () {
16
-   local IFS='>'
17
-   read -d '<' TAG VALUE
18
-   TAG=$(tr '\n' ' ' <<< $TAG | sed 's/  */ /g; s/ *$//')
28
+function xmlgetnext () {
29
+    local IFS='>'
30
+    read -d '<' TAG VALUE
31
+    # by design, the first TAG/VALUE pair is empty
32
+    # to avoid infinite loops at end of file parsing we return an error
33
+    # the next time we find an empty TAG
34
+    if test -z "$TAG"; then
35
+        test ${xmlgetnext_firstentry:-1} -eq 1 && xmlgetnext_firstentry=0 || return 1;
36
+    fi
37
+    # process $TAG only if necessary
38
+    local _TAG=$(printf '%q' $TAG)
39
+    if test ${_TAG:0:1} = '$'; then
40
+        TAG=$(tr '\n' ' ' <<< $TAG | sed 's/  */ /g; s/ *$//')
41
+    fi
19 42
 }
20 43
 
21 44
 function sqlite_request () {
22
-    sqlite3 "$in_ram_database" <<< "$1"
45
+    if ! sqlite3 "$in_ram_database" <<< "$1"; then
46
+        register_state
47
+    fi
48
+}
49
+
50
+function xmlremovecomments () {
51
+    sed -ri 's/<(!--|script>)/\n&/;s/(<\/script|--)>/&\n/' $setxml
52
+    sed -ri '/<(script>|!--).*(<\/script|--)>/d;/<(script>|!--)/,/(<\/script|--)>/d' $setxml
53
+}
54
+
55
+function trap_break () {
56
+    trap '' INT
57
+    echo "stop requested"
58
+    register_state
23 59
 }
24 60
 
25 61
 function trap_exit () {
62
+    trapped_rc=$?
63
+    trap '' INT
64
+    rm -f $aircrafts $aircraft $setxml
65
+    if test ! -e $in_ram_database; then
66
+        exit
67
+    fi
68
+    test $trapped_rc -ne 0 && register_state
26 69
     echo "updating installation status"
27
-    for ac in $(sqlite_request 'select printf("%i:%s/%s", aircrafts.id, aircrafts.name, setxml.file) from aircrafts inner join setxml where aircrafts.id = setxml.variantof and setxml.installed != 0;'); do
70
+    for ac in $(sqlite_request 'select printf("%i:%s/%s", aircrafts.id, aircrafts.name, setxml.file)
71
+                                from aircrafts inner join setxml
72
+                                where aircrafts.id = setxml.variantof and setxml.installed != 0;'); do
28 73
         ac_path=${ac#*:}
29 74
         if test ! -e $fgaddon_path/$ac_path-set.xml; then
30 75
             sqlite_request "update setxml set installed = 0 where file = '${ac_path#*/}' and variantof = ${ac%:*}"
... ...
@@ -43,9 +88,15 @@ function trap_exit () {
43 88
         fi
44 89
         sqlite_request "update setxml set installed = $install_type
45 90
                         where exists (
46
-                            select 1 from aircrafts where name = '${ac/\/}' and setxml.variantof = id
91
+                            select 1
92
+                            from aircrafts
93
+                            where name = '${ac/\/}' and setxml.variantof = id
47 94
                         )"
48 95
     done
96
+    missing_setxml=$(sqlite_request "select name from aircrafts where id not in (select variantof from setxml)")
97
+    if test -n "$missing_setxml"; then
98
+        echo "missing setxml config: $missing_setxml"
99
+    fi
49 100
     if test -r "$database" && md5sum $in_ram_database | sed "s,$in_ram_database,$database," | md5sum --status -c -; then
50 101
         rm -f $in_ram_database
51 102
         echo "no changes in $database"
... ...
@@ -60,146 +111,317 @@ function trap_exit () {
60 111
         rm -f $in_ram_database
61 112
         echo "nothing can be done with $database !"
62 113
     fi
63
-    rm -f $aircrafts $aircraft $setxml
64 114
 }
65 115
 
66
-update_database () {
67
-    let progress++
68
-    echo "[ ${progress}${total:+/$total} ] $ac"
116
+function register_state () {
117
+set +x
118
+    sqlite_request "drop table if exists recover_rev"
119
+    sqlite_request "create table recover_rev (
120
+                        revkey text,
121
+                        revision integer,
122
+                        revauthor text,
123
+                        revdate integer
124
+                    )"
125
+    for revkey in ${!revision[@]}; do
126
+        sqlite_request "insert into recover_rev values (
127
+                            '$revkey',
128
+                            ${revision[$revkey]:-0},
129
+                            '${revauthor[$revkey]}',
130
+                            ${revdate[$revkey]:-0}
131
+                        )"
132
+    done
133
+    sqlite_request "drop table if exists recover_setxmlmodified"
134
+    sqlite_request "create table if not exists recover_setxmlmodified (
135
+                        sx text
136
+                    )"
137
+    for sx in ${!setxmlmodified[@]}; do
138
+        sqlite_request "insert into recover_setxmlmodified values (
139
+                            '$sx'
140
+                        )"
141
+    done
142
+    set +x
143
+    exit
144
+}
145
+
146
+function update_database () {
147
+    echo "[ ${#revision[@]} ] ${ac:1}"
69 148
 
70
-    dbupdate=$(sqlite_request "select revision from aircrafts where name is '$ac'")
149
+    dbupdate=$(sqlite_request "select revision from aircrafts where name is '${ac:1}'")
71 150
     if test -z "$dbupdate"; then
72 151
         sqlite_request "insert into aircrafts (name, revision, date, author)
73
-                        values ('$ac', ${revision[$ac]}, ${revdate[$ac]}, '${revauthor[$ac]}')"
152
+                        values ('${ac:1}', ${revision[$ac]}, ${revdate[$ac]}, '${revauthor[$ac]}')"
74 153
     elif test $dbupdate -lt ${revision[$ac]}; then
75 154
         sqlite_request "update aircrafts set
76 155
                             revision = ${revision[$ac]},
77 156
                             author   = '${revauthor[$ac]}',
78 157
                             date = ${revdate[$ac]}
79
-                        where name is '$ac'"
158
+                        where name is '${ac:1}'"
80 159
     fi
81
-    id=$(sqlite_request "select id from aircrafts where name is '$ac'")
160
+    id=$(sqlite_request "select id from aircrafts where name is '${ac:1}'")
82 161
 
83
-    for sx in ${setxmlmodified[$ac]}; do
84
-        test -n "${_sx[$ac/$sx]}" && continue
85
-        _sx[$ac/$sx]="already done"
86
-        unset description long_description author flight_model in_sim
162
+    for sx in ${!setxmlmodified[@]}; do
163
+        unset include include_rootpath
164
+        [[ "$sx" =~ ^"${ac:1}/" ]] || continue
165
+        for col in ${!data[@]}; do
166
+            data[$col]=
167
+        done
168
+        sx=${sx#*/}
87 169
         echo " -> $sx"
88
-        svn export --quiet --force --revision ${revision[$ac]} $fgaddon_svn/$ac/$sx-set.xml $setxml
170
+        if ! svn export --quiet --force $fgaddon_svn/${ac:1}/$sx-set.xml $setxml; then
171
+            register_state
172
+        fi
173
+        xmlremovecomments
174
+        unset xmlgetnext_firstentry property
89 175
         while xmlgetnext; do
90
-            if [[ "$TAG" = @($attributes_case) ]]; then
91
-                test -n "$in_sim" && eval "${TAG//-/_}=\"$VALUE\""
92
-                test -n "$description" \
93
-                  -a -n "$long_description" \
94
-                  -a -n "$author" \
95
-                  -a -n "$flight_model" \
96
-                  -a -n "$type" && break
97
-            elif test "$TAG" = 'sim'; then
98
-                in_sim=1
99
-            elif test "$TAG" = '/sim'; then
100
-                break
176
+            case "${TAG:0:1}" in
177
+                ''|'?'|'!')
178
+                    continue;;
179
+                /)
180
+                    property=${property%/*};;
181
+                *)
182
+                    if test "${TAG: -1}" != '/'; then
183
+                        property+=/${TAG%% *}
184
+                    fi
185
+#                    property+=/${TAG%% *}
186
+#                    if test "${TAG: -1}" = '/'; then
187
+#                        _TAG=${TAG:0:-1}
188
+#                        test "${_TAG#* }" != "${_TAG}" && eval "${_TAG#* }"
189
+#                        property=${property%/*}
190
+#                    fi;;
191
+            esac
192
+
193
+            if [[ "$TAG" =~ ^"PropertyList include=" ]]; then
194
+                include_rootpath=${include%/*}
195
+                test $include = $include_rootpath && unset include_rootpath
196
+                eval $(echo ${TAG#* })
197
+                [[ "$include" =~ ^Aircraft/Generic/ ]] && unset include include_rootpath && continue
198
+                if [[ "$include" =~ ^'../' ]]; then
199
+                    if test -n "$include_rootpath"; then
200
+                        if [[ "$include_rootpath" =~ '/' ]]; then
201
+                            include_rootpath=${include_rootpath%/*}
202
+                        else
203
+                            unset include_rootpath
204
+                        fi
205
+                    else
206
+                        ac_save=$ac
207
+                        unset ac
208
+                    fi
209
+                    include=${include/\.\.\/}
210
+                fi
211
+                if ! svn cat $fgaddon_svn/${ac:1}/${include_rootpath:+$include_rootpath/}$include >> $setxml; then
212
+                    register_state
213
+                fi
214
+                xmlremovecomments
215
+            fi
216
+
217
+            if [[ "$property" = /PropertyList@($data_pattern) ]]; then
218
+                eval "data[${property/\/PropertyList}]=\"${VALUE//\"/\\\"}\""
219
+                data[${property/\/PropertyList}]=$(tr '\n' ' ' <<< ${data[${property/\/PropertyList}]} | sed -r 's/^\s*//;s/\s+/ /g;s/\s*$//')
101 220
             fi
102
-        done < $setxml
103 221
 
104
-        test -z "$description" \
105
-          -a -z "$long_description" \
106
-          -a -z "$author" \
107
-          -a -z "$flight_model" \
108
-          -a -z "$type" && echo "WARNING: no info found, skipping" && continue
222
+            if test -n "$_TAG"; then
223
+                # _TAG non-null means xml props ends with /
224
+                # need to go back of last property
225
+                property=${property/%\/${_TAG%% *}}
226
+                unset _TAG
227
+            fi
109 228
 
110
-        if test -n "$description" -a -z "$flight_model"; then
111
-            grep -qi 'jsbsim' <<< "$description" && flight_model='jsb'
112
-            grep -qi 'yasim' <<< "$description" && flight_model='yasim'
113
-        fi
229
+            # continue parsing (while loop) until everything's found
230
+            for col in ${!data[@]}; do
231
+                test -z "${data[$col]}" && continue 2
232
+            done
233
+            break # everything's found
234
+        done < $setxml
114 235
 
115
-        if test -n "$long_description"; then
116
-            long_description=$(sed 's/^\s*//g' <<< $long_description | tr '\n' ' ')
236
+        if eval "test -z \"$data_test_null\""; then
237
+            echo "WARNING: no info found, skipping"
238
+            continue
117 239
         fi
118 240
 
119 241
         known=$(sqlite_request "select variantof from setxml where file is '$sx'")
120 242
         if test -n "$known"; then
121
-            for attribute in ${attributes[@]}; do
122
-                dbvalue=$(sqlite_request "select $attribute from setxml where file is '$sx'")
123
-                eval "wgvalue=\$$attribute"
124
-                if test "$dbvalue" != "$wgvalue" -a -n "$wgvalue"; then
125
-                    sqlite_request "update setxml set $attribute = '$wgvalue' where file is '$sx'"
243
+            for col in ${!data[@]}; do
244
+                dbvalue=$(sqlite_request "select '$col'
245
+                                          from setxml
246
+                                          where file is '$sx' and variantof = $known")
247
+                if test "$dbvalue" != "${data[$col]}" -a -n "${data[$col]}"; then
248
+                    sqlite_request "update setxml
249
+                                    set '$col' = '${data[$col]//\'/\'\'}'
250
+                                    where file is '$sx' and variantof = $known"
126 251
                 fi
127 252
             done
128 253
         else
129
-            sqlite_request "insert into setxml values ('$sx', $id, '$description', '$long_description', '$author', '$type', '$flight_model', 0)"
254
+            values="'$sx', $id, "
255
+            for col in ${!data[@]}; do
256
+                values+="'${data[$col]//\'/\'\'}', "
257
+            done
258
+            values+=0
259
+            sqlite_request "insert into setxml values ($values)"
260
+        fi
261
+        test -n "$ac_save" && ac=$ac_save
262
+        unset setxmlmodified[${ac:1}/$sx]
263
+    done
264
+    unset revision[$ac]
265
+}
266
+
267
+function apply_revision () {
268
+    for ac in "${!revision[@]}"; do
269
+        update_database
270
+        if test -d $fgaddon_path/${ac:1}/.svn \
271
+        && test "$(svn info --show-item=url $fgaddon_path/${ac:1})" != "$fgaddon_svn/${ac:1}" \
272
+        || test -d $fgaddon_path/${ac:1} -a ! -d $fgaddon_path/${ac:1}/.svn; then
273
+            echo "INFO: local ${ac:1} installed out from repo" >&2
130 274
         fi
131 275
     done
132 276
 }
133 277
 
278
+trap trap_break INT
134 279
 trap trap_exit EXIT
135 280
 
136
-test -e $database && cp $database $in_ram_database
281
+stty -echoctl
282
+
283
+declare -A revision revauthor revdate setxmlmodified files revpath
284
+data_pattern=$(printf "%s|" ${!data[@]})
285
+data_pattern=${data_pattern:0:-1}
286
+data_test_null=$(printf '${data[%s]}' ${!data[@]})
287
+
288
+if test -e $database; then
289
+    cp $database $in_ram_database
290
+    sql_cols=$(sqlite_request "pragma table_info(setxml)" | awk -F'|' '{printf("%s %s ", $2, $3)}')
291
+    script_cols="file text variantof integer "
292
+    for col in ${!data[@]}; do
293
+        script_cols+="$col ${data["$col"]} "
294
+    done
295
+    script_cols+="installed integer " # last space is important
296
+    if test "$sql_cols" != "$script_cols"; then
297
+        echo "ALERT: datbase version mismatch !"
298
+        exit 1
299
+    fi
300
+    if sqlite_request '.tables' | grep -q 'recover_' && test -z "$1"; then
301
+        echo "recovering from previous saved state"
302
+        eval $(sqlite_request "select printf('revision[%s]=%u;revauthor[%s]=%s;revdate[%s]=%u;',
303
+                                       revkey, revision,
304
+                                       revkey, revauthor,
305
+                                       revkey, revdate)
306
+                               from recover_rev")
307
+        eval $(sqlite_request "select printf('setxmlmodified[%s]=1;', sx)
308
+                               from recover_setxmlmodified")
309
+        sqlite_request "drop table recover_rev"
310
+        sqlite_request "drop table recover_setxmlmodified"
311
+        apply_revision
312
+        exit
313
+    fi
314
+fi
315
+
316
+sqlite_request "create table if not exists aircrafts (
317
+                    id integer primary key,
318
+                    name text,
319
+                    revision integer,
320
+                    date integer,
321
+                    author text)"
137 322
 
138
-sqlite_request "create table if not exists aircrafts (id integer primary key, name text, revision integer, date integer, author text)"
139
-sqlite_request "create table if not exists setxml (file text, variantof integer, description text, long_description text, author text, type text, flight_model text, installed integer)"
323
+sqlite_request "create table if not exists setxml (
324
+                    file text,
325
+                    variantof integer,
326
+                    $(for col in ${!data[@]}; do printf "'%s' %s, " $col ${data[$col]}; done)
327
+                    installed integer)"
140 328
 
141
-attributes_case=$(printf "%s|" "${attributes[@]}")
142
-attributes_case=${attributes_case:0:-1}
143 329
 latest_revision=$(sqlite_request "select max(revision) from aircrafts")
144 330
 
331
+# for debugging purpose
332
+if test -n "$2"; then
333
+    ac=_${1%/*}
334
+    revision[$ac]=1
335
+    revdate[$ac]=0
336
+    revauthor[$ac]=foobar
337
+    setxmlmodified[${ac:1}/${1#*/}]=1
338
+    set -x
339
+    update_database
340
+    set +x
341
+    exit
342
+elif test -n "$1"; then
343
+    ac=_${1%/*}
344
+    eval $(sqlite_request "select printf('revision[_%s]=%s;revdate[_%s]=%i;revauthor[_%s]=%s;',
345
+                                            name, revision,
346
+                                            name, date,
347
+                                            name, author)
348
+                           from aircrafts
349
+                           where name = '${ac:1}'")
350
+    setxmlmodified[${ac:1}/${1#*/}]=1
351
+    if test -z "${revision[$ac]}"; then
352
+        echo "aircraft ${ac:1} not found"
353
+        rm $in_ram_database
354
+        exit
355
+    fi
356
+    update_database
357
+    exit
358
+fi
359
+
145 360
 echo "downloading FGADDON history from revision ${latest_revision:-0}"
146 361
 svn log --revision ${latest_revision:-0}:HEAD --xml --verbose $fgaddon_svn > $aircrafts
147 362
 
363
+total=$(grep -c '<logentry' $aircrafts)
364
+progress=0
365
+
366
+echo parsing history
367
+
148 368
 while xmlgetnext; do
149 369
     case "$TAG" in
150 370
         'logentry revision='*)
151 371
             eval $(echo ${TAG#* })
152
-            unset revdate revauthor ac path_list setxmlmodified
372
+            for action in ${!revpath[@]}; do
373
+                unset revpath[$action]
374
+            done
153 375
         ;;
154 376
         'author')
155
-            revauthor=$VALUE
377
+            revauthor=${VALUE//\'/\'\'}
156 378
         ;;
157 379
         'date')
158 380
             revdate=$(date +%s -d "$VALUE")
159 381
         ;;
160 382
         'path '*)
161
-            path_list[${#path_list[@]}]="$VALUE"
383
+            TAG=${TAG#* }
384
+            TAG=${TAG// /;}
385
+            TAG=${TAG//-/_}
386
+            eval $(echo ${TAG// /;})
387
+            path=(${VALUE//\// })
388
+            if test $kind = 'file' -a ${#path[@]} -gt 3; then
389
+                revpath[$action]+="$VALUE "
390
+            elif test $kind = 'dir' -a ${#path[@]} -eq 3 -a $action = 'D'; then
391
+                files[_${path[2]}]=0
392
+                unset revision[_${path[2]}] revauthor[_${path[2]}] revdate[_${path[2]}]
393
+                for sx in ${!setxmlmodified[@]}; do
394
+                    [[ "$sx" =~ "${path[2]}/" ]] && unset setxmlmodified[$sx]
395
+                done
396
+            fi
162 397
         ;;
163 398
         '/logentry')
164
-            revlog[${#revlog[@]}]=$(
165
-                printf '%s\n' "${path_list[@]}" | awk -F/ -v revision=$revision -v revauthor=$revauthor -v revdate=$revdate -v dq='"' '
166
-                {
167
-                    a[$4]++
168
-                    if ($5 ~ "-set.xml$") b[$4]=b[$4] " " gensub("-set.xml$", "", "1", $5)
169
-                }
170
-                END {
171
-                    for (i in a)
172
-                        printf("<revision[%s]=%i;revauthor[%s]=%s;revdate[%s]=%i;%s>",
173
-                                i, revision,
174
-                                i, revauthor,
175
-                                i, revdate,
176
-                                b[i] != "" ? "setxmlmodified[" i "]=" dq gensub("^ ", "", "g", b[i]) " ${setxmlmodified[" i "]}" dq ";" : "")
177
-                }')
178
-        ;;
179
-        '/log')
180
-            unset revision revauthor revdate setxmlmodified
181
-            declare -A revision revauthor revdate setxmlmodified
182
-            analyse () {
183
-                while xmlgetnext; do
184
-                    test -z "$TAG" -a ${#revision[@]} -eq 0 && continue
185
-                    case $TAG in
186
-                        'BEGIN') continue;;
187
-                        'END'  ) break 2;;
188
-                    esac
189
-                    echo $TAG
190
-                done <<< "<BEGIN>${revlog[@]}<END>"
191
-            }
192
-            eval $(analyse)
193
-            total=${#revision[@]}
194
-            declare -A _sx
195
-            for ac in "${!revision[@]}"; do
196
-                update_database
197
-                if test -d $fgaddon_path/$ac/.svn \
198
-                && test "$(svn info --show-item=url $fgaddon_path/$ac)" != "$fgaddon_svn/$ac" \
199
-                || test -d $fgaddon_path/$ac -a ! -d $fgaddon_path/$ac/.svn; then
200
-                    echo "INFO: local $ac installed out from repo" >&2
399
+            for item in ${revpath[D]}; do
400
+                path=(${item//\// })
401
+                [[ "${path[3]}" =~ "-set.xml" ]] && unset setxmlmodified[${path[2]}/${path[3]/-set.xml}]
402
+                files[_${path[2]}]=$(( --files[_${path[2]}] ))
403
+                if test ${files[_${path[2]}]} -le 0; then
404
+                    unset revision[_${path[2]}] revauthor[_${path[2]}] revdate[_${path[2]}]
201 405
                 fi
202 406
             done
407
+            for action in A M R; do
408
+                for item in ${revpath[$action]}; do
409
+                    path=(${item//\// })
410
+                    revision[_${path[2]}]=$revision
411
+                    revauthor[_${path[2]}]=$revauthor
412
+                    revdate[_${path[2]}]=$revdate
413
+                    [[ "${path[3]}" =~ "-set.xml" ]] && setxmlmodified[${path[2]}/${path[3]/-set.xml}]=1
414
+                    test $action = 'A' && files[_${path[2]}]=$(( ++files[_${path[2]}] ))
415
+                done
416
+            done
417
+            newprogress=$((++logentry * 100 / $total))
418
+            if test $(( $newprogress - $progress )) -ge ${progress_granularity:-1}; then
419
+                progress=$newprogress
420
+                echo "$progress% (${#revision[@]})"
421
+            fi
422
+        ;;
423
+        '/log')
424
+            apply_revision
203 425
             break
204 426
         ;;
205 427
     esac
+1 -2
.fgfs/fgfs_function
... ...
@@ -157,9 +157,8 @@ function fgfs () {
157 157
             elif which sqlite3 > /dev/null 2>&1 \
158 158
             && test -r $FGADDON/fgaddon.db \
159 159
             && test $(sqlite3 $FGADDON/fgaddon.db <<< "select count(file) from setxml where file is '${fgfs_arg}'") -eq 1; then
160
-                model=$(sqlite3 $FGADDON/fgaddon.db <<< "select name from aircrafts inner join setxml on aircrafts.id = setxml.variantof where setxml.file is '${fgfs_arg}-set.xml'")
160
+                model=$(sqlite3 $FGADDON/fgaddon.db <<< "select name from aircrafts inner join setxml on aircrafts.id = setxml.variantof where setxml.file is '${fgfs_arg}'")
161 161
                 read -q "REPLY?download $model ? (y/N) "
162
-                read
163 162
                 if test -n "$REPLY" && test ${REPLY:l} = "y"; then
164 163
                     svn co https://svn.code.sf.net/p/flightgear/fgaddon/trunk/Aircraft/$model $FGADDON/Aircraft/$model
165 164
                     fgfs_args+=("--aircraft=$fgfs_arg")