Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (26.133 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 from 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
  # move the extracted compiler folder
282
  mv -f "$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

    
369
  return 0
370
}
371

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

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

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

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

    
469
  return 0
470
}
471

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

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

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

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

    
525
  return 0
526
}
527

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

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

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

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

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

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

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

    
693
  exit 0
694
}
695

    
696
################################################################################
697
# SCRIPT ENTRY POINT                                                           #
698
################################################################################
699

    
700
main "$@"