Statistics
| Branch: | Tag: | Revision:

amiro-blt / tools / compiler / GCC / gccsetup.sh @ ec50c96e

History | View | Annotate | Download (26.157 KB)

1
################################################################################
2
# AMiRo-BLT is an bootloader and toolchain designed for the Autonomous Mini    #
3
# Robot (AMiRo) platform.                                                      #
4
# Copyright (C) 2016..2020  Thomas Schöpping et al.                            #
5
#                                                                              #
6
# This program is free software: you can redistribute it and/or modify         #
7
# it under the terms of the GNU General Public License as published by         #
8
# the Free Software Foundation, either version 3 of the License, or            #
9
# (at your option) any later version.                                          #
10
#                                                                              #
11
# This program is distributed in the hope that it will be useful,              #
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of               #
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                #
14
# GNU General Public License for more details.                                 #
15
#                                                                              #
16
# You should have received a copy of the GNU General Public License            #
17
# along with this program.  If not, see <http://www.gnu.org/licenses/>.        #
18
#                                                                              #
19
# This research/work was supported by the Cluster of Excellence Cognitive      #
20
# Interaction Technology 'CITEC' (EXC 277) at Bielefeld University, which is   #
21
# funded by the German Research Foundation (DFG).                              #
22
################################################################################
23

    
24
#!/bin/bash
25

    
26
# load library
27
source "$(dirname ${BASH_SOURCE[0]})/../../bash/setuplib.sh"
28

    
29
### print welcome text #########################################################
30
# Prints a welcome message to standard out.
31
#
32
# usage:      printWelcomeText
33
# arguments:  n/a
34
# return:     n/a
35
#
36
function printWelcomeText {
37
  printf "######################################################################\n"
38
  printf "#                                                                    #\n"
39
  printf "#                     Welcome to the GCC setup!                      #\n"
40
  printf "#                                                                    #\n"
41
  printf "######################################################################\n"
42
  printf "#                                                                    #\n"
43
  printf "# Copyright (c) 2016..2020  Thomas Schöpping                         #\n"
44
  printf "#                                                                    #\n"
45
  printf "# This is free software; see the source for copying conditions.      #\n"
46
  printf "# There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR  #\n"
47
  printf "# A PARTICULAR PURPOSE. The development of this software was         #\n"
48
  printf "# supported by the Excellence Cluster EXC 227 Cognitive Interaction  #\n"
49
  printf "# Technology. The Excellence Cluster EXC 227 is a grant of the       #\n"
50
  printf "# Deutsche Forschungsgemeinschaft (DFG) in the context of the German #\n"
51
  printf "# Excellence Initiative.                                             #\n"
52
  printf "#                                                                    #\n"
53
  printf "######################################################################\n"
54
}
55

    
56
### print help #################################################################
57
# Prints a help text to standard out.
58
#
59
# usage:      printHelp
60
# arguments:  n/a
61
# return:     n/a
62
#
63
function printHelp {
64
  printInfo "printing help text\n"
65
  printf "usage:    $(basename ${BASH_SOURCE[0]}) [-h|--help] [-i|--install] [-c|--change] [-q|--quit] [--log=<file>]\n"
66
  printf "\n"
67
  printf "options:  -h, --help\n"
68
  printf "              Print this help text.\n"
69
  printf "          -i, --install\n"
70
  printf "              Install another version.\n"
71
  printf "          -u, --uninstall\n"
72
  printf "              Unistall a version.\n"
73
  printf "          -c, --change\n"
74
  printf "              Change the default version.\n"
75
  printf "          -q, --quit\n"
76
  printf "              Quit the script.\n"
77
  printf "          --log=<file>\n"
78
  printf "              Specify a log file.\n"
79
}
80

    
81
### detect installed versions ##################################################
82
# Detect all installed version of arm-none-eabi-gcc, if any.
83
#
84
# usage:      detectInstalledVersions <binarray> <current> [<current_idx>]
85
# arguments:  <binarray>
86
#                 Array variable to store all detected binary paths to. 
87
#             <current>
88
#                 Variable to store the currently active binary to.
89
#             <current_idx>
90
#                 Index of the curretly selected version in the output array (<binarray>).
91
# return:     n/a
92
#
93
function detectInstalledVersions {
94
  local armgcc_command=$(command -v arm-none-eabi-gcc)
95
  local armgcc_commanddir=${HOME}/gcc-none-eabi
96
  local armgcc_currentbin=""
97
  local armgcc_installdir=${HOME}/gcc-none-eabi
98
  local armgcc_bins=()
99
  local armgcc_bincnt=0
100

    
101
  # check for already installed versions
102
  if [ -n "$armgcc_command" ]; then
103
    # follow the link to the actual binary
104
    armgcc_commanddir=$(dirname $armgcc_command)
105
    armgcc_currentbin=$armgcc_command
106
    while [ -L $armgcc_currentbin ]; do
107
      # differentiate between relative and absolute paths
108
      if [[ $(readlink $armgcc_currentbin) = /* ]]; then
109
        armgcc_currentbin=$(readlink $armgcc_currentbin)
110
      else
111
        armgcc_currentbin=$(realpath $(dirname $armgcc_currentbin)/$(readlink $armgcc_currentbin))
112
      fi
113
    done
114
    # the installation location is assumed to be two directories up
115
    armgcc_installdir=$(realpath $(dirname ${armgcc_currentbin})/../..)
116
    # list all detected instalations
117
    for dir in $(ls -d ${armgcc_installdir}/*/); do
118
      if [ -f ${dir}/bin/arm-none-eabi-gcc ]; then
119
        armgcc_bins[$armgcc_bincnt]=${dir}bin/arm-none-eabi-gcc
120
        armgcc_bincnt=$((armgcc_bincnt + 1))
121
      fi
122
    done
123

    
124
    # set the output variables
125
    eval "$1=(${armgcc_bins[*]})"
126
    eval $2="$armgcc_currentbin"
127
    if [ -n "$3" ]; then
128
      for (( bin=0; bin<${#armgcc_bins[@]}; ++bin )); do
129
        if [ ${armgcc_bins[bin]} = "$armgcc_currentbin" ]; then
130
          eval $3=$bin
131
        fi
132
      done
133
    fi
134
  else
135
    eval "$1=()"
136
    eval $2=""
137
    if [ -n "$3" ]; then
138
      eval $3=""
139
    fi
140
  fi
141
}
142

    
143
### install new version ########################################################
144
# Fetches an installation package from the internet, installs it and expands
145
# the $PATH environment variable (via .bashrc) if required.
146
#
147
# usage:      installNewVersion [-i|--install=<path>] [-l|--link=<path>]
148
# argumenst:  -i, --install <path>
149
#                 Path where to install the new version to.
150
#             -l, --link <path>
151
#                 Path where to create according links.
152
# return:     0
153
#                 No error or warnign occurred.
154
#             1
155
#                 Warning: Installation aborted by user.
156
#             -1
157
#                 Error: specified URL can not be reached.
158
#             -2
159
#                 Error: Missing dependecny.
160
#
161
function installNewVersion {
162
  local installbasedir=${HOME}/gcc-arm-embedded
163
  local linkdir="/usr/bin"
164

    
165
  # check dependencies
166
  checkCommands wget
167
  if [ $? -ne 0 ]; then
168
    printError "Missing dependencies detected.\n"
169
    return -2
170
  fi
171

    
172
  # parse arguments
173
  local otherargs=()
174
  while [ $# -gt 0 ]; do
175
    if ( parseIsOption $1 ); then
176
      case "$1" in
177
        -i=*|--install=*)
178
          installbasedir=$(realpath "${1#*=}"); shift 1;;
179
        -i|--install)
180
          installbasedir="$2"; shift 2;;
181
        -l=*|--link=*)
182
          linkdir=$(realpath "${1#*=}"); shift 1;;
183
        -l|--link)
184
          linkdir="$2"; shift 2;;
185
        *) # sanity check (exit with error)
186
          printError "invalid option: $1\n"; shift 1;;
187
      esac
188
    else
189
      otherargs+=("$1")
190
      shift 1
191
    fi
192
  done
193

    
194
  # read download URL form user
195
  printf "In order to install a compiler, you have to specify a download link for the according installation file.\n"
196
  printf "For this project, the GNU Arm Embedded Toolchain is recommended:\n"
197
  printf "  https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm\n"
198
  printf "The following link can be used to install the GNU Arm Embedded Toolchain version 8-2018-q4-major:\n"
199
  printf "  https://developer.arm.com/-/media/Files/downloads/gnu-rm/8-2018q4/gcc-arm-none-eabi-8-2018-q4-major-linux.tar.bz2\n"
200
  printf "\n"
201
  printLog "read installation url from user\n"
202
  local armgcc_downloadurl=""
203
  while [ -z "$armgcc_downloadurl" ]; do
204
    read -p "Download link for the installation file: " -e armgcc_downloadurl
205
    if [ -z "$armgcc_downloadurl" ]; then
206
      printWarning "installation aborted by user\n"
207
      return 1
208
    fi
209
    # check whether url is valid
210
    wget --spider -r "$armgcc_downloadurl" &>/dev/null
211
    if [ $? -ne 0 ]; then
212
      printError "'$armgcc_downloadurl' can not be reached\n"
213
      return -1
214
    fi
215
  done
216
  printLog "user selected $armgcc_downloadurl\n"
217

    
218
  # if the file already exists, ask the user if it should be downloaded again
219
  local armgcc_tarball=$(basename $(wget --spider -r "$armgcc_downloadurl" 2>&1 | \
220
                                    grep "^--" | \
221
                                    tail -n 1 | \
222
                                    awk '{print $NF}'))
223
  if [ -f "$armgcc_tarball" ]; then
224
    printWarning "$armgcc_tarball already exists. Delete and redownload? [y/n]\n"
225
    local userinput=""
226
    readUserInput "YyNn" userinput
227
    case "$userinput" in
228
      Y|y)
229
        rm "$armgcc_tarball"
230
        wget "$armgcc_downloadurl" -O "$armgcc_tarball" | tee -a $LOG_FILE
231
        ;;
232
      N|n)
233
        ;;
234
      *) # sanity check (exit with error)
235
        printError "unexpected argument: $userinput\n";;
236
    esac
237
  else
238
    wget "$armgcc_downloadurl" -O "$armgcc_tarball" | tee -a $LOG_FILE
239
  fi
240

    
241
  # extract tarball
242
  printInfo "extracting ${armgcc_tarball}...\n"
243
  tar -jxf "$armgcc_tarball" | tee -a $LOG_FILE
244
  local compilerdir=`tar --bzip2 -tf ${armgcc_tarball} | sed -e 's@/.*@@' | uniq`
245

    
246
  # install gcc arm embedded
247
  printLog "read installation directory from user\n"
248
  local installdir=""
249
  read -p "Installation directory: " -i ${installbasedir}/${compilerdir} -e installdir
250
  printLog "user selected $installdir\n"
251
  linkdir=$(dirname ${installdir})
252
  printLog "read link directory\n"
253
  read -p "Link directory: " -i $linkdir -e linkdir
254
  printLog "user selected $linkdir\n"
255
  # if the installation path already exists, ask user to overwrite
256
  if [ -d "$installdir" ]; then
257
    printWarning "$installdir already exists. Overwrite? [y/n]\n"
258
    local userinput=""
259
    readUserInput "YyNn" userinput
260
    case "$userinput" in
261
      Y|y)
262
        ;;
263
      N|n)
264
        printWarning "installation aborted by user\n"
265
        return 1
266
        ;;
267
      *) # sanity check (exit with error)
268
        printError "invalid option: $userinput\n";;
269
    esac
270
  # make sure the whole ínstallation path exists
271
  else
272
    while [ ! -d $(dirname "$installdir") ]; do
273
      local dir=$(dirname "$installdir") 
274
      while [ ! -d $(dirname "$dir") ]; do
275
        dir=$(dirname "$dir")
276
      done
277
      echo "mkdir $dir"
278
      mkdir "$dir"
279
    done
280
  fi
281
  # copy the extracted compiler folder
282
  cp -fR "$compilerdir" "$installdir"
283
  # make sure whole link path exists
284
  while [ ! -d "$linkdir" ]; do
285
    local dir="$linkdir"
286
    while [ ! -d $(dirname "$linkdir") ]; do
287
      dir=$(dirname "$dir")
288
    done
289
    mkdir "$dir"
290
  done
291
  # create / overwrite links
292
  local linkpath=$(realpath --relative-base=$linkdir ${installdir}/bin/)
293
  ls ${installdir}/bin/ | xargs -i ln -sf ${linkpath}/{} ${linkdir}/{}
294
  printInfo "default version set to $(arm-none-eabi-gcc -dumpversion)\n"
295

    
296
  # append the link directory to the PATH environment variable if required
297
  if [[ ! "$linkdir" = *"$PATH"* ]]; then
298
    local bashrc_file=${HOME}/.bashrc
299
    local bashrc_identifier="##### AMiRo ENVIRONMENT CONFIGURATION #####"
300
    local bashrc_note="# DO NOT EDIT THESE LINES MANUALLY!"
301
    local bashrc_entry="export PATH=\$PATH:$linkdir"
302

    
303
    # find and edit old entry, or append a new one to the file
304
    local bashrc_idlines=$(grep -x -n "$bashrc_identifier" "$bashrc_file" | cut -f1 -d:) # string of line numbers
305
    bashrc_idlines=(${bashrc_idlines//"\n"/" "}) # array of line numbers
306
    case ${#bashrc_idlines[@]} in
307

    
308
      # append a new entry to the BASHRC_FILE
309
      0)
310
        # make sure the last line is empty
311
        if [[ ! $(tail -1 $bashrc_file) =~ ^[\ \t]*$ ]]; then
312
          printf "\n" >> $bashrc_file
313
        fi
314
        # append text to file
315
        sed -i '$a'"$bashrc_identifier\n$bashrc_note\n$bashrc_entry\n$bashrc_identifier\n" $bashrc_file
316
        # print note
317
        printInfo "Your $bashrc_file has been updated. You need to source it to apply the changes in your environment.\n"
318
        read -p "  Understood!"
319
        ;;
320

    
321
      # extend the old entry
322
      2)
323
        # don't do anything if the line is already present
324
        local bashrc_entrylines=$(grep -x -n "$bashrc_entry" $bashrc_file | cut -f1 -d:) # string of line numbers
325
        bashrc_entrylines=(${bashrc_entrylines//"\n"/" "}) # array of line numbers
326
        if [[ ${#bashrc_entrylines[@]} = 0 ]]; then
327
          # insert the entry before the closing identifier
328
          sed -i "${bashrc_idlines[1]}"'i'"$bashrc_entry" $bashrc_file
329
          # print note
330
          printInfo "Your $bashrc_file has been updated. You need to source it to apply the changes in your environment.\n"
331
          read -p "  Understood!"
332
        elif [[ ${#bashrc_entrylines[@]} -eq 1 && ( ${bashrc_entrylines[0]} -lt ${bashrc_idlines[0]} || ${bashrc_entrylines[0]} -gt ${bashrc_idlines[1]} ) ]]; then
333
          # print an error that there is an entry at the wrong place
334
          printError "corrupted entry in your $bashrc_file detected\n"
335
          printf "The following entry was found at the wrong place:\n"
336
          printf "\n"
337
          printf "$bashrc_entry\n"
338
          printf "\n"
339
          printf "To fix this, delete the line and rerun this setup.\n"
340
          read -p "  Understood!"
341
        elif [[ ${#bashrc_entrylines[@]} -gt 1 ]]; then
342
          # print an error that there are multiple entries
343
          printError "corrupted entry in your $bashrc_file detected\n"
344
          printf "There are multiple identical entries in your $bashrc_file file.\n"
345
          printf "To fix it, make sure that it contains the following line exactly once:\n"
346
          printf "\n"
347
          printf "$bashrc_entry\n"
348
          printf "\n"
349
          read -p "  Understood!"
350
        fi
351
        ;;
352

    
353
      # error state (corrupted entry detected)
354
      *)
355
        printError "unable to append link directory to \$PATH variable\n"
356
        printf "There seems to be a broken entry in your $bashrc_file file.\n"
357
        printf "To fix it, make sure that the following line appears exactly twice and encloses your AMiRo related settings:\n"
358
        printf "\n"
359
        printf "$bashrc_identifier\n"
360
        printf "\n"
361
        read -p "  Understood!"
362
        ;;
363
    esac
364
  fi
365

    
366
  # clean up the current directory
367
  rm "$armgcc_tarball"
368
  rm -rf "$compilerdir"
369

    
370
  return 0
371
}
372

    
373
### uninstall a version ########################################################
374
# Select an installed version and uninstall it from the system.
375
#
376
# usage:      uninstallVersion <versions> <current_idx> <linkdir>
377
# arguments:  <version>
378
#                 Array of available versions (full path to binary).
379
#             <current_idx>
380
#                 Index of the currently selected version in the array.
381
#             <linkdir>
382
#                 Path where to delete old links.
383
# return:     0
384
#                 No error or warning occurred.
385
#             1
386
#                 Warning: Installation aborted by user.
387
#             -1
388
#                 Error: An exception occurred.
389
#
390
function uninstallVersion {
391
  local versions=("${!1}")
392
  local current_idx="$2"
393
  local linkdir="$3"
394

    
395
  # check whether at least two installations were detected
396
  if [ ${#versions[@]} -eq 0 ]; then
397
    printError "no installation detected\n"
398
    return -1
399
  else
400
    # print all available versions
401
    printInfo "choose the installation to uninstall to or type 'A' to abort:\n"
402
    for (( cnt=0; cnt<${#versions[@]}; ++cnt )); do
403
      if [ $cnt -eq $current_idx ]; then
404
        printf "*%3u: %s\n" $(($cnt + 1)) ${versions[$cnt]}
405
      else
406
        printf " %3u: %s\n" $(($cnt + 1)) ${versions[$cnt]}
407
      fi
408
    done
409

    
410
    # read user selection
411
    printLog "read user slection\n"
412
    local userinput=""
413
    while [ -z $userinput ] ; do
414
      read -p "your selection: " -e userinput
415
      printLog "user selection: $userinput\n"
416
      if [[ ! "$userinput" =~ ^[0-9]+$ ]] || [ ! "$userinput" -gt 0 ] || [ ! "$userinput" -le ${#versions[@]} ] && [[ ! "$userinput" =~ ^[Aa]$ ]]; then
417
        printWarning "Please enter an integer between 1 and ${#versions[@]} or 'A' to abort.\n"
418
        userinput=""
419
      fi
420
      if [ ${#versions[@]} -gt 1 ] && [ $((userinput - 1)) -eq $current_idx ]; then
421
        printWarning "Unable to uninstall currently selected version (as long as there are others).\n"
422
        userinput=""
423
      fi
424
    done
425

    
426
    if [[ "$userinput" =~ ^[Aa]$ ]]; then
427
      printWarning "aborted by user\n"
428
      return 1
429
    else
430
      local idx=$((userinput - 1))
431
      printf "\n"
432
      # prompt selected and aks user for confirmation
433
      printInfo "${versions[$idx]} will be removed. Continue? [y/n]\n"
434
      readUserInput "YyNn" userinput
435
      case "$userinput" in
436
        Y|y)
437
          ;;
438
        N|n)
439
          printWarning "uninstallation process aborted by user\n"
440
          return 1
441
          ;;
442
        *) # sanity check (exit with error)
443
          printError "invalid option: $userinput\n"
444
          return -1
445
          ;;
446
      esac
447
      # find and delete any links pointing to the version to be deleted
448
      for link in `find $linkdir -maxdepth 1 -type l`; do
449
        local l=$link
450
        # follow the link to the actual binary
451
        while [ -L $l ]; do
452
          # differentiate between relative and absolute paths
453
          if [[ $(readlink $l) = /* ]]; then
454
            l=$(readlink $l)
455
          else
456
            l=$(realpath $(dirname $l)/$(readlink $l))
457
          fi
458
        done
459
        # delete the link if it points to the version to be uninstalled
460
        if [ $(dirname $l) == $(dirname ${versions[$idx]}) ]; then
461
          rm $link
462
        fi
463
      done
464
      # delete the version directory (assumed to be one directory up)
465
      rm -rf $(realpath $(dirname ${versions[$idx]})/..)
466
      printInfo "${versions[$idx]} has been removed.\n"
467
    fi
468
  fi
469

    
470
  return 0
471
}
472

    
473
### change default version #####################################################
474
# Change the default arm-none-eabi-gcc version.
475
#
476
# usage:      changeDefaultVersion <versions> <linkdir>
477
# argumenst:  <versions>
478
#                 Array of available versions (full path to binary).
479
#             <linkdir>
480
#                 Path where to delete old and create new links.
481
# return:     0
482
#                 No error or warnign occurred.
483
#             -1
484
#                 Error: no installation detected.
485
#
486
function changeDefaultVersion {
487
  local versions=("${!1}")
488
  local linkdir="$2"
489

    
490
  # check whether an installation was detected
491
  if [ ${#versions[@]} -eq 0 ]; then
492
    printError "no installation detected\n"
493
    return -1
494
  else
495
    # print all available versions
496
    printInfo "choose the installation to switch to or type 'A' to abort:\n"
497
    for (( cnt=0; cnt<${#versions[@]}; ++cnt )); do
498
      printf "  %2u: %s\n" $(($cnt + 1)) ${versions[$cnt]}
499
    done
500

    
501
    # read user selection
502
    printLog "read user slection\n"
503
    local userinput=""
504
    while [[ ! "$userinput" =~ ^[0-9]+$ ]] || [ ! "$userinput" -gt 0 ] || [ ! "$userinput" -le ${#versions[@]} ] && [[ ! "$userinput" =~ ^[Aa]$ ]]; do
505
      read -p "your selection: " -e userinput
506
      printLog "user selection: $userinput\n"
507
      if [[ ! "$userinput" =~ ^[0-9]+$ ]] || [ ! "$userinput" -gt 0 ] || [ ! "$userinput" -le ${#versions[@]} ] && [[ ! "$userinput" =~ ^[Aa]$ ]]; then
508
        printWarning "Please enter an integer between 1 and ${#versions[@]} or 'A' to abort.\n"
509
      fi
510
    done
511

    
512
    if [[ "$userinput" =~ ^[Aa]$ ]]; then
513
      printWarning "aborted by user\n"
514
    else
515
      local idx=$((userinput - 1))
516
      # find and delete old links
517
      rm `find $linkdir -maxdepth 1 -type l | grep -Ev "*[0-9]\.[0-9]\.[0-9]"`
518
      # create new links with relative or absolute paths
519
      local bindir=$(dirname ${versions[$idx]})
520
      local linkpath=$(realpath --relative-base=$linkdir $bindir)
521
      ls $bindir | xargs -i ln -sf $linkpath/{} $linkdir/{}
522
      printInfo "default version set to $(arm-none-eabi-gcc -dumpversion)\n"
523
    fi
524
  fi
525

    
526
  return 0
527
}
528

    
529
### main function of this script ###############################################
530
# The IDE setup lets the user select an IDE of choice.
531
# As of now, only QtCreator is supported.
532
#
533
# usage:      see function printHelp
534
# arguments:  see function printHelp
535
# return:     0
536
#                 No error or warning occurred.
537
#
538
function main {
539
  # print welcome/info text if not suppressed
540
  if [[ $@ != *"--noinfo"* ]]; then
541
    printWelcomeText
542
  else
543
    printf "######################################################################\n"
544
  fi
545
  printf "\n"
546

    
547
  # if --help or -h was specified, print the help text and exit
548
  if [[ $@ == *"--help"* || $@ == *"-h"* ]]; then
549
    printHelp
550
    printf "\n"
551
    quitScript
552
  fi
553

    
554
  # set log file if specified
555
  if [[ $@ == *"--log"* ]] || [[ $@ == *"--LOG"* ]]; then
556
    # get the parameter (file name)
557
    local cmdidx=1
558
    while [[ ! "${!cmdidx}" = "--log"* ]] && [[ ! "${!cmdidx}" = "--LOG"* ]]; do
559
      cmdidx=$[cmdidx + 1]
560
    done
561
    local cmd="${!cmdidx}"
562
    local logfile=""
563
    if [[ "$cmd" = "--log="* ]] || [[ "$cmd" = "--LOG="* ]]; then
564
      logfile=${cmd#*=}
565
    else
566
      local filenameidx=$((cmdidx + 1))
567
      logfile="${!filenameidx}"
568
    fi
569
    # optionally force silent appending
570
    if [[ "$cmd" = "--LOG"* ]]; then
571
      setLogFile --option=c --quiet "$logfile" LOG_FILE
572
    else
573
      setLogFile "$logfile" LOG_FILE
574
      printf "\n"
575
    fi
576
  fi
577
  # log script name
578
  printLog "this is $(realpath ${BASH_SOURCE[0]})\n"
579

    
580
  # detect installed versions and inform user
581
  local installedversions=()
582
  local currentversion=""
583
  local currentversionidx="n/a"
584
  detectInstalledVersions installedversions currentversion currentversionidx
585
  case "${#installedversions[@]}" in
586
    0)
587
      printInfo "no installation has been detected\n";;
588
    1)
589
      printInfo "1 installation has been detected:\n";;
590
    *)
591
      printInfo "${#installedversions[@]} installations have been detected:\n";;
592
  esac
593
  for (( idx=0; idx<${#installedversions[@]}; ++idx )); do
594
    if [ ${installedversions[$idx]} = "$currentversion" ]; then
595
      printInfo "  * ${installedversions[$idx]}\n"
596
    else
597
      printInfo "    ${installedversions[$idx]}\n"
598
    fi
599
  done
600
  printf "\n"
601

    
602
  # parse arguments
603
  local otherargs=()
604
  while [ $# -gt 0 ]; do
605
    if ( parseIsOption $1 ); then
606
      case "$1" in
607
        -h|--help) # already handled; ignore
608
          shift 1;;
609
        -i|--install)
610
          if [ -z "$currentversion" ]; then
611
            installNewVersion
612
          else
613
            installNewVersion --install=$(realpath $(dirname $currentversion)/../..) --link=$(realpath $(dirname $currentversion)/../..)
614
          fi
615
          detectInstalledVersions installedversions currentversion currentversionidx
616
          printf "\n"; shift 1;;
617
        -u|--uninstall)
618
          if [ ! -z "$currentversion" ]; then
619
            uninstallVersion installedversions[@] $currentversionidx $(realpath $(dirname $currentversion)/../..)
620
            detectInstalledVersions installedversions currentversion currentversionidx
621
          else
622
            printError "no installation detected\n"
623
          fi
624
          printf "\n"; shift 1;;
625
        -c|--change)
626
          if [ ! -z "$currentversion" ]; then
627
            changeDefaultVersion installedversions[@] $(realpath $(dirname $currentversion)/../..)
628
          else
629
            printError "no installation detected\n"
630
          fi
631
          printf "\n"; shift 1;;
632
        -q|--quit)
633
          quitScript; shift 1;;
634
        --log=*|--LOG=*) # already handled; ignore
635
          shift 1;;
636
        --log|--LOG) # already handled; ignore
637
          shift 2;;
638
        --noinfo) # already handled; ignore
639
          shift 1;;
640
        *)
641
          printError "invalid option: $1\n"; shift 1;;
642
      esac
643
    else
644
      otherargs+=("$1")
645
      shift 1
646
    fi
647
  done
648

    
649
  # interactive menu
650
  while ( true ); do
651
    # main menu info prompt and selection
652
    printInfo "GCC setup main menu\n"
653
    printf "Please select one of the following actions:\n"
654
    printf "  [I] - install another version\n"
655
    printf "  [U] - uninstall a version\n"
656
    printf "  [C] - change default version\n"
657
    printf "  [Q] - quit this setup\n"
658
    local userinput=""
659
    readUserInput "IiUuCcQq" userinput
660
    printf "\n"
661

    
662
    # evaluate user selection
663
    case "$userinput" in
664
      I|i)
665
        if [ -z "$currentversion" ]; then
666
          installNewVersion
667
        else
668
          installNewVersion --install=$(realpath $(dirname $currentversion)/../..) --link=$(realpath $(dirname $currentversion)/../..)
669
        fi
670
        detectInstalledVersions installedversions currentversion currentversionidx
671
        printf "\n";;
672
      U|u)
673
        if [ ! -z "$currentversion" ]; then
674
          uninstallVersion installedversions[@] $currentversionidx $(realpath $(dirname $currentversion)/../..)
675
          detectInstalledVersions installedversions currentversion currentversionidx
676
        else
677
          printError "no installation detected\n"
678
        fi
679
        printf "\n";;
680
      C|c)
681
        if [ ! -z "$currentversion" ]; then
682
          changeDefaultVersion installedversions[@] $(realpath $(dirname $currentversion)/../..)
683
        else
684
          printError "no installation detected\n"
685
        fi
686
        printf "\n";;
687
      Q|q)
688
        quitScript;;
689
      *) # sanity check (exit with error)
690
        printError "unexpected argument: $userinput\n";;
691
    esac
692
  done
693

    
694
  exit 0
695
}
696

    
697
################################################################################
698
# SCRIPT ENTRY POINT                                                           #
699
################################################################################
700

    
701
main "$@"