Statistics
| Branch: | Tag: | Revision:

amiro-os / tools / ide / QtCreator / QtCreatorSetup.sh @ 7387fb42

History | View | Annotate | Download (27 KB)

1
################################################################################
2
# AMiRo-OS is an operating system designed for the Autonomous Mini Robot       #
3
# (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 QtCreator 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] [-c|--create=<module>] [-d|--delete=<module>] [-q|--quit] [--log=<file>]\n"
66
  printf "\n"
67
  printf "options:  -h, --help\n"
68
  printf "              Print this help text.\n"
69
  printf "          -c, --create <module>\n"
70
  printf "              Create project files for a sigle module or for all modules (<module>='*').\n"
71
  printf "          -d, --delete <module>\n"
72
  printf "              Delete projet files of a single module or of all modules (<module>='*').\n"
73
  printf "          -q, --quit\n"
74
  printf "              Quit the script.\n"
75
  printf "          --log=<file>\n"
76
  printf "              Specify a log file.\n"
77
}
78

    
79
### read directory where to create/delete projects #############################
80
# Read the directory where to create/delete project files from user.
81
#
82
# usage:      getProjectDir <pathvar>
83
# arguments:  <pathvar>
84
#                 Variable to store the selected path to.
85
# return:     n/a
86
#
87
function getProjectDir {
88
  local amiroosdir=$(realpath $(dirname $(realpath ${BASH_SOURCE[0]}))/../../../)
89
  local input=""
90

    
91
  printLog "reading path for project files from user...\n"
92
  read -p "Path where to create/delete project files: " -i $amiroosdir -e input
93
  printLog "user selected path $(realpath $input)\n"
94
  eval $1="$(realpath $input)"
95
}
96

    
97
### retrieves the ARM-NONE-EABI-GCC include directory ##########################
98
# Retrieves the include directory of the currently set arm-none-eabi-gcc.
99
#
100
# usage:      retrieveGccIncludeDir <path>
101
# arguments:  <path>
102
#                 Variable to store the path to.
103
# return:    0
104
#                 No error or warning occurred.
105
#            -1
106
#                 Error: Command 'arm-none-eabi-gcc' not found.
107
#            -2
108
#                 Error: include directory could not be resolved.
109
#
110
function retrieveGccIncludeDir {
111
  local binpath=$(which arm-none-eabi-gcc)
112
  local gccincpath=""
113

    
114
  # retrieve binary path or link
115
  if [ -z "$binpath" ]; then
116
    printError "command 'arm-none-eabi-gcc' not found\n"
117
    return -1
118
  else 
119

    
120
    # traverse any links
121
    while [ -L "$binpath" ]; do
122
      binpath=$(realpath $(dirname $binpath)/$(readlink $binpath))
123
    done
124
    printInfo "gcc-arm-none-eabi detected: $binpath\n"
125

    
126
    # return include path
127
    gccincpath=$(realpath $(dirname ${binpath})/../arm-none-eabi/include/)
128
    if [ ! -d "$gccincpath" ]; then
129
      printWarning "$gccincpath does not exist\n"
130
      return -2
131
    else
132
      eval $1="$gccincpath"
133
      return 0
134
    fi
135
  fi
136
}
137

    
138
### detect available modules ###################################################
139
# Detect all avalable modules supported by AMiRo-OS.
140
#
141
# usage:      detectModules <modulearray>
142
# arguments:  <modulearray>
143
#                 Array variable to store all detected modules to.
144
# return:     n/a
145
#
146
function detectModules {
147
  local modules_detected=()
148
  local modulesdir=$(realpath $(dirname $(realpath ${BASH_SOURCE[0]}))/../../../modules)
149

    
150
  # detect all available modules (via directories)
151
  for dir in $(ls -d ${modulesdir}/*/); do
152
    modules_detected[${#modules_detected[@]}]=$(basename $dir)
153
  done
154

    
155
  # set the output variable
156
  eval "$1=(${modules_detected[*]})"
157
}
158

    
159
### create project files for a single or all modules ###########################
160
# Create project files for a single or all modules.
161
#
162
# usage:      createProject <modules> [-m|--module=<module>] [-p|--path=<path>] [--gcc=<path>] [-o|--out=<var>] [--gccout=<var>]
163
# arguments:  <modules>
164
#                 Array containing all modules available.
165
#             -m, --module <module>
166
#                 Name (folder name) of the module for which project files shall be generated, or '*' to generate for all modules.
167
#             -p, --path <path>
168
#                 Path where to create the project files.
169
#             --gcc=<path>
170
#                 Path to the GCC include directory.
171
#             -o, --out <var>
172
#                 Variable to store the path to.
173
#             --gccout=<var>
174
#                 Variable to store the path to the GCC include directory to.
175
#                 If this optional arguments is absent, ths function will ask for user input.
176
# return:     0
177
#                 No error or warning occurred.
178
#             1
179
#                 Aborted by user.
180
#             -1
181
#                 No modules available.
182
#             -2
183
#                 The specified <module> could not be found.
184
#             -3
185
#                 Parsing the project for the specified module failed.
186
#             -4
187
#                 Missing dependencies.
188
#
189
function createProject {
190
  local gccincludedir=""
191
  local gccoutvar=""
192
  local includes=()
193
  local makedir=""
194
  local makedirs=()
195
  local module=""
196
  local modules=("${!1}")
197
  local modules2generate=()
198
  local modulesdir=$(realpath $(dirname $(realpath ${BASH_SOURCE[0]}))/../../../modules)
199
  local otherargs=()
200
  local outvar=""
201
  local parse_state=""
202
  local projectdir=""
203
  local projectfiles=()
204
  local quotes="\'\"\´\`\„\“"
205
  local rawout=""
206
  local sourcefile=""
207
  local sourcefiles=()
208
  local userdir=$(pwd)
209
  local userinput=""
210

    
211
  # check dependencies
212
  checkCommands make
213
  if [ $? -ne 0 ]; then
214
    printError "Missing dependencies detected.\n"
215
    return -4
216
  fi
217

    
218
  # parse arguments
219
  while [ $# -gt 0 ]; do
220
    if ( parseIsOption $1 ); then
221
      case "$1" in
222
        -m=*|--module=*)
223
          module="${1#*=}"; shift 1;;
224
        -m|--module)
225
          module="$2"; shift 2;;
226
        -p=*|--path=*)
227
          projectdir=$(realpath "${1#*=}"); shift 1;;
228
        -p|--path)
229
          projectdir=$(realpath "$2"); shift 2;;
230
        --gcc=*)
231
          gccincludedir=$(realpath "${1#*=}"); shift 1;;
232
        --gcc)
233
          gccincludedir=$(realpath "$2"); shift 2;;
234
        -o=*|--out=*)
235
          outvar=${1#*=}; shift 1;;
236
        -o|--out)
237
          outvar=$2; shift 2;;
238
        --gccout=*)
239
          gccoutvar=$(realpath "${1#*=}"); shift 1;;
240
        --gccout)
241
          gccoutvar=$(realpath "$2"); shift 2;;
242
        *)
243
          printError "invalid option: $1\n"; shift 1;;
244
      esac
245
    else
246
      otherargs+=("$1")
247
      shift 1
248
    fi
249
  done
250

    
251
  # sanity check for the modules variable
252
  if [ -z "${modules[*]}" ]; then
253
    printError "no modules available\n"
254
    return -1
255
  fi
256

    
257
  # select module
258
  if [ -z $module ]; then
259
    # list all available modules
260
    printInfo "select a module, type '*' for all or type 'A' to abort:\n"
261
    for (( idx=0; idx<${#modules[@]}; ++idx )); do
262
      printf "%4u: %s\n" $(($idx + 1)) "${modules[$idx]}"
263
    done
264
    # read user input
265
    printLog "read user selection\n"
266
    userinput=""
267
    while [[ ! "$userinput" =~ ^[0-9]+$ ]] || [ ! "$userinput" -gt 0 ] || [ ! "$userinput" -le ${#modules[@]} ] && [[ ! "$userinput" =~ ^(\*|[Aa])$ ]]; do
268
      read -p "your selection: " -e userinput
269
      printLog "user selection: $userinput\n"
270
      if [[ ! "$userinput" =~ ^[0-9]+$ ]] || [ ! "$userinput" -gt 0 ] || [ ! "$userinput" -le ${#modules[@]} ] && [[ ! "$userinput" =~ ^(\*|[Aa])$ ]]; then
271
        printWarning "Please enter an integer between 1 and ${#modules[@]}, '*' to select all or 'A' to abort.\n"
272
      fi
273
    done
274
    if [[ "$userinput" =~ ^[0-9]+$ ]]; then
275
      # store selection
276
      modules2generate=(${modules[$(($userinput - 1))]})
277
    elif [[ "$userinput" =~ ^\*$ ]]; then
278
      modules2generate=(${modules[@]})
279
    elif [[ "$userinput" =~ ^[Aa]$ ]]; then
280
      printWarning "aborted by user\n"
281
      return 1
282
    fi
283
    printf "\n"
284
  else
285
    # check whether the specified module is available
286
    if [[ ! "${modules[@]}" =~ "$module" ]]; then
287
      printError "module '$module' not available\n"
288
      return -2
289
    else
290
      modules2generate=($module)
291
    fi
292
  fi
293

    
294
  # read absolute project directory if required
295
  if [ -z "$projectdir" ]; then
296
    getProjectDir projectdir
297
    printf "\n"
298
  fi
299

    
300
  # check for existing project files
301
  for module in ${modules2generate[@]}; do
302
    projectfiles+=($(find ${projectdir} -maxdepth 1 -type f -regextype posix-extended -regex "^.*/${module}\.(includes|files|config|creator)$" | sort))
303
  done
304
  if [ ${#projectfiles[@]} != 0 ]; then
305
    printWarning "The following files will be overwritten:\n"
306
    for pfile in ${projectfiles[@]}; do
307
      printWarning "\t$(basename $pfile)\n"
308
    done
309
    userinput=""
310
    printInfo "Continue and overwrite? [y/n]\n"
311
    readUserInput "YyNn" userinput
312
    case "$userinput" in
313
      Y|y)
314
        ;;
315
      N|n)
316
        printWarning "project generation aborted by user\n"
317
        return 1
318
        ;;
319
      *)
320
        printError "unexpected input: ${userinput}\n"; return -999;;
321
    esac
322
    printf "\n"
323
  fi
324

    
325
  # retrieve absolute GCC include path
326
  if [ -z "$gccincludedir" ]; then
327
    retrieveGccIncludeDir gccincludedir
328
  fi
329

    
330
  # generate all modules
331
  cd "$projectdir"
332
  for module in ${modules2generate[@]}; do
333
    # print message
334
    printInfo "generating QtCreator project files for the $module module...\n"
335

    
336
    # run make, but only run the GCC preprocessor and produce no binaries
337
    sourcefiles=()
338
    sourcefile=""
339
    parse_state="WAIT_FOR_INCLUDE_COMPILE_MAKE"
340
    makedir=""
341
    makedirs=()
342
    # capture all output from make and GCC and append the return value of make as last line
343
    printInfo "processing project (this may take a while)...\n"
344
    rawout=$(make --directory ${modulesdir}/${module} --always-make USE_OPT="-v -E -H" USE_VERBOSE_COMPILE="no" OUTFILES="" 2>&1 && echo $?)
345
    # check whether the make call was successfull
346
    if [[ $(echo "${rawout}" | tail -n 1) != "0" ]]; then
347
      printError "executing 'make' in module directory failed\n"
348
      cd "$userdir"
349
      return -3
350
    else
351
      # cleanup
352
      make --directory ${modulesdir}/${module} clean &>/dev/null
353
    fi
354
    # extract file names from raw output
355
    IFS=$'\n'; rawout=($rawout); unset IFS
356
    for line in "${rawout[@]}"; do
357
      case $parse_state in
358
        WAIT_FOR_INCLUDE_COMPILE_MAKE)
359
          # lines stating include files look like:
360
          # ... <../relative/path/to/file>
361
          if [[ "$line" =~ ^\.+[[:blank:]].+\..+$ ]]; then
362
            sourcefile=${line##* }
363
            if [[ ! "$sourcefile" =~ ^/ ]]; then
364
              sourcefile=$(realpath ${makedirs[-1]}/${sourcefile})
365
            fi
366
            sourcefiles[${#sourcefiles[@]}]="$sourcefile"
367
          # whenever the next source file is processed, a message appears like:
368
          # Compiling <filename>
369
          elif [[ "$line" =~ ^Compiling[[:blank:]](.+\..+)$ ]]; then
370
            printf "."
371
            sourcefile=${BASH_REMATCH[1]}
372
            parse_state="WAIT_FOR_COMPILERCALL"
373
          # if make is called again in another directory or a nested make call leaves the directory, a message appears like:
374
          # make[1]: Entering directory 'directory'
375
          # make[999]: Verzeichnis „directory“ wird verlassen
376
          elif [[ "$line" =~ ^make(\[[0-9]+\])?:([[:alnum:]]|[[:blank:]])*[$quotes].*[$quotes]([[:alnum:]]|[[:blank:]])*$ ]]; then
377
            # extract directory path
378
            makedir=$(echo ${line} | grep -oE "[${quotes}].*[${quotes}]" | grep -oE "[^${quotes}].*[^${quotes}]")
379
            # if the makedirs stack is empty or the directory does not mathc the last entry
380
            if [ ${#makedirs[@]} == 0 ] || [ "${makedir}" != "${makedirs[-1]}" ]; then
381
              # push the directory to the stack
382
              makedirs+=(${makedir})
383
            else
384
              # pop the directory from the stack
385
              unset makedirs[-1]
386
            fi
387
          fi;;
388
        WAIT_FOR_COMPILERCALL)
389
          # wait for the actual call of the compiler to retrieve the full path to the source file
390
          if [[ "$line" == *${sourcefile}* ]]; then
391
            line="${line%%${sourcefile}*}${sourcefile}"
392
            line="${line##* }"
393
            if [[ "$line" =~ ^/ ]]; then
394
              # aboslute path
395
              sourcefile=$line
396
            else
397
              # relative path
398
              sourcefile=$(realpath ${makedirs[-1]}/${line##* })
399
            fi
400
            sourcefiles[${#sourcefiles[@]}]="$sourcefile"
401
            parse_state="WAIT_FOR_INCLUDE_COMPILE_MAKE"
402
          fi;;
403
      esac
404
    done
405
    printf "\n"
406
    # sort and remove duplicates
407
    IFS=$'\n'; sourcefiles=($(sort --unique <<< "${sourcefiles[*]}")); unset IFS
408

    
409
    # extract include paths
410
    includes=()
411
    for source in ${sourcefiles[*]}; do
412
      includes[${#includes[@]}]="$(dirname ${source})"
413
    done
414
    # sort and remove duplicates
415
    IFS=$'\n'; includes=($(sort --unique <<< "${includes[*]}")); unset IFS
416

    
417
    # generate the .incldues file, containing all include paths
418
    echo "" > ${projectdir}/${module}.includes
419
    for inc in ${includes[*]}; do
420
      echo "$inc" >> ${projectdir}/${module}.includes
421
    done
422
    # generate the .files file, containing all source files
423
    echo "" > ${projectdir}/${module}.files
424
    for source in ${sourcefiles[*]}; do
425
      # skip GCC files
426
      if [[ ! "$source" =~ .*/gcc.* ]]; then
427
        echo "$source" >> ${projectdir}/${module}.files
428
      fi
429
    done
430
    # generate a default project configuration file if it doesn't exist yet
431
    if [ ! -f ${projectdir}/${module}.config ]; then
432
      echo "// Add predefined macros for your project here. For example:" > ${projectdir}/${module}.config
433
      echo "// #define YOUR_CONFIGURATION belongs here" >> ${projectdir}/${module}.config
434
    fi
435
    # generate a default .creator file if it doesn't exist yet
436
    if [ ! -f ${projectdir}/${module}.creator ]; then
437
      echo "[general]" > ${projectdir}/${module}.creator
438
    fi
439
  done
440

    
441
  # go back to user directory
442
  cd "$userdir"
443

    
444
  # fill the output variables
445
  if [ ! -z "$outvar" ]; then
446
    eval $outvar="$projectdir"
447
  fi
448
  if [ ! -z "$gccoutvar" ]; then
449
    eval $gccoutvar="$gccincludedir"
450
  fi
451

    
452
  return 0
453
}
454

    
455
### delete project files for a single or all modules ###########################
456
# Deletes all project files and optionally .user files, too.
457
#
458
# usage:      deleteProject [-p|--path=<path>] [-m|--module=<module>] [-o|--out=<var>] [-w|--wipe=<flag>]
459
# arguments:  -p, --path <path>
460
#                 Path where to delete the project files.
461
#             -m, --module <module>
462
#                 Module name for which the project files shall be deleted or '*' to delete for all modules.
463
#             -o, --out <var>
464
#                 Variable to store the path to.
465
#             -w, --wipe <flag>
466
#                 Flag whether to delete .user files as well (must be either "true" or "false").
467
# return:     0
468
#               No error or warning occurred.
469
#             1
470
#               Aborted by user.
471
#             2
472
#               There are no project files (for the specified module) at the specified location.
473
#
474
function deleteProject {
475
  local files=()
476
  local module=""
477
  local modules=()
478
  local modules2delete=()
479
  local otherargs=()
480
  local outvar=""
481
  local projectdir=""
482
  local userinput=""
483
  local wipe=""
484

    
485
  # parse arguments
486
  while [ $# -gt 0 ]; do
487
    if ( parseIsOption $1 ); then
488
      case "$1" in
489
        -p=*|--path=*)
490
          projectdir=$(realpath "${1#*=}"); shift 1;;
491
        -p|--path)
492
          projectdir=$(realpath "$2"); shift 2;;
493
        -m=*|--module=*)
494
          module="${1#*=}"; shift 1;;
495
        -m|--module)
496
          module="${2}"; shift 2;;
497
        -o=*|--out=*)
498
          outvar=${1#*=}; shift 1;;
499
        -o|--out)
500
          outvar=$2; shift 2;;
501
        -w=*|--wipe=*)
502
          wipe="${1#*=}"; shift 1;;
503
        -w|--wipe)
504
          wipe="$2"; shift 2;;
505
        *)
506
          printError "invalid option: $1\n"; shift 1;;
507
      esac
508
    else
509
      otherargs+=("$1")
510
      shift 1
511
    fi
512
  done
513

    
514
  # sanity checks on parameters
515
  if [ ! -z $wipe ] && [[ ! "$wipe" =~ ^(true|false)$ ]]; then
516
    printWarning "invalid value set to 'wipe' argument\n"
517
    printInfo "I will act as if there was no '--wipe' argument and ask for input later.\n"
518
    wipe=""
519
  fi
520

    
521
  # read absolute project directory if required
522
  if [ -z "$projectdir" ]; then
523
    getProjectDir projectdir
524
    printf "\n"
525
  fi
526

    
527
  # retrieve all modules in the specified directory
528
  modules=($(find "${projectdir}" -maxdepth 1 -type f -regextype posix-extended -regex "^.+\.(includes|files|config|creator|cflags|cxxflags|creator\.user(\..+)?)$" | grep -oE "/[^/\.]+\." | grep -oE "[^/].+[^\.]" | sort --unique))
529

    
530
  # check whether there are any project files at the specified location
531
  if [ ${#modules[@]} -eq 0 ]; then
532
    printWarning "no projects detected at '${projectdir}'\n"
533
    return 2
534
  fi
535

    
536
  # select module
537
  if [ -z "$module" ]; then
538
    # list all available modules
539
    printInfo "select a module, type '*' for all or type 'A' to abort:\n"
540
    for (( idx=0; idx<${#modules[@]}; ++idx )); do
541
      printf "%4u: %s\n" $(($idx + 1)) "${modules[$idx]}"
542
    done
543
    # read user input
544
    printLog "read user selection\n"
545
    userinput=""
546
    while [[ ! "$userinput" =~ ^[0-9]+$ ]] || [ ! "$userinput" -gt 0 ] || [ ! "$userinput" -le ${#modules[@]} ] && [[ ! "$userinput" =~ ^(\*|[Aa])$ ]]; do
547
      read -p "your selection: " -e userinput
548
      printLog "user selection: $userinput\n"
549
      if [[ ! "$userinput" =~ ^[0-9]+$ ]] || [ ! "$userinput" -gt 0 ] || [ ! "$userinput" -le ${#modules[@]} ] && [[ ! "$userinput" =~ ^(\*|[Aa])$ ]]; then
550
        printWarning "Please enter an integer between 1 and ${#modules[@]}, '*' to select all or 'A' to abort.\n"
551
      fi
552
    done
553
    if [[ "$userinput" =~ ^[0-9]+$ ]]; then
554
      # store selection
555
      modules2delete=(${modules[$(($userinput - 1))]})
556
    elif [[ "$userinput" =~ ^\*$ ]]; then
557
      modules2delete=(${modules[@]})
558
    elif [[ "$userinput" =~ ^[Aa]$ ]]; then
559
      printWarning "aborted by user\n"
560
      return 1
561
    else
562
      printError "unexpected user input: ${userinput}\n"
563
      return -999
564
    fi
565
    printf "\n"
566
  else
567
    # check whether the specified module is available
568
    if [[ ! "${modules[@]}" =~ "$module" ]]; then
569
      printWarning "there are no project files for module '$module' at location '$projectdir'\n"
570
      return 2
571
    else
572
      modules2delete=($module)
573
    fi
574
  fi
575

    
576
  # check for .user files
577
  files=()
578
  for module in ${modules2delete[@]}; do
579
    files+=($(find "${projectdir}" -maxdepth 1 -type f -regextype posix-extended -regex "^.*${module}\.creator\.user(\..+)?)$"))
580
  done
581

    
582
  # read wipe information if required
583
  if [ ${#files[@]} -gt 0 ] &&  [ -z "$wipe" ]; then
584
    userinput=""
585
    printInfo "Wipe user data as well? [y/n]\n"
586
    readUserInput "YyNn" userinput
587
    case "$userinput" in
588
      Y|y)
589
        wipe="true";;
590
      N|n)
591
        wipe="false";;
592
      *)
593
        printError "unexpected input: ${userinput}\n"; return -999;;
594
    esac
595
    printf "\n"
596
  fi
597

    
598
  # retrieve all files
599
  files=()
600
  for module in ${modules2delete[@]}; do
601
    if [ "$wipe" == "true" ]; then
602
      files+=($(find "${projectdir}" -maxdepth 1 -type f -regextype posix-extended -regex "^.*${module}\.(includes|files|config|creator|cflags|cxxflags|creator\.user(\..+)?)$"))
603
    else
604
      files+=($(find "${projectdir}" -maxdepth 1 -type f -regextype posix-extended -regex "^.*${module}\.(includes|files|config|creator|cflags|cxxflags)$"))
605
    fi
606
  done
607

    
608
  # list all files to be deleted and ask for confirmation
609
  if [ ${#files[@]} -gt 0 ]; then
610
    printWarning "The following files will be deleted:\n"
611
    for file in ${files[@]}; do
612
      printWarning "\t$(basename ${file})\n"
613
    done
614
    userinput=""
615
    printInfo "Do you want to continue? [y/n]\n"
616
    readUserInput "YyNn" userinput
617
    case "$userinput" in
618
      Y|y)
619
        ;;
620
      N|n)
621
        printWarning "aborted by user\n"
622
        return 1;;
623
      *)
624
        printError "unexpected input: ${userinput}\n"; return -999;;
625
    esac
626
  else
627
    printInfo "no files to delete\n"
628
  fi
629

    
630
  # finally delete the files
631
  for file in ${files[@]}; do
632
    rm ${file} 2>&1 | tee -a $LOG_FILE
633
  done
634

    
635
  # store the path to the output variable, if required
636
  if [ ! -z "$outvar" ]; then
637
    eval $outvar="$projectdir"
638
  fi
639

    
640
  return 0
641
}
642

    
643
### main function of this script ###############################################
644
# Creates, deletes and wipes QtCreator project files for any module supported by AMiRo-OS.
645
#
646
# usage:      see function printHelp
647
# arguments:  see function printHelp
648
# return:     0
649
#                 No error or warning ocurred.
650
#
651
function main {
652
  local cmd=""
653
  local cmdidx=""
654
  local filenameidx=""
655
  local logfile=""
656
  local modules=()
657
  local otherargs=()
658
  local userinput=""
659

    
660
  # print welcome/info text if not suppressed
661
  if [[ $@ != *"--noinfo"* ]]; then
662
    printWelcomeText
663
  else
664
    printf "######################################################################\n"
665
  fi
666
  printf "\n"
667

    
668
  # if --help or -h was specified, print the help text and exit
669
  if [[ $@ == *"--help"* || $@ == *"-h"* ]]; then
670
    printHelp
671
    printf "\n"
672
    quitScript
673
  fi
674

    
675
  # set log file if specified
676
  if [[ $@ == *"--log"* ]] || [[ $@ == *"--LOG"* ]]; then
677
    # get the parameter (file name)
678
    cmdidx=1
679
    while [[ ! "${!cmdidx}" = "--log"* ]] && [[ ! "${!cmdidx}" = "--LOG"* ]]; do
680
      cmdidx=$[cmdidx + 1]
681
    done
682
    cmd="${!cmdidx}"
683
    logfile=""
684
    if [[ "$cmd" = "--log="* ]] || [[ "$cmd" = "--LOG="* ]]; then
685
      logfile=${cmd#*=}
686
    else
687
      filenameidx=$((cmdidx + 1))
688
      logfile="${!filenameidx}"
689
    fi
690
    # optionally force silent appending
691
    if [[ "$cmd" = "--LOG"* ]]; then
692
      setLogFile --option=c --quiet "$logfile" LOG_FILE
693
    else
694
      setLogFile "$logfile" LOG_FILE
695
      printf "\n"
696
    fi
697
  fi
698
  # log script name
699
  printLog "this is $(realpath ${BASH_SOURCE[0]})\n"
700

    
701
  # detect available modules and inform user
702
  detectModules modules
703
  case "${#modules[@]}" in
704
    0)
705
      printInfo "no module has been detected\n";;
706
    1)
707
      printInfo "1 module has been detected:\n";;
708
    *)
709
      printInfo "${#modules[@]} modules have been detected:\n"
710
  esac
711
  for (( idx=0; idx<${#modules[@]}; ++idx )); do
712
    printInfo "  - ${modules[$idx]}\n"
713
  done
714
  printf "\n"
715

    
716
  # parse arguments
717
  while [ $# -gt 0 ]; do
718
    if ( parseIsOption $1 ); then
719
      case "$1" in
720
        -h|--help) # already handled; ignore
721
          shift 1;;
722
        -c=*|--create=*)
723
          createProject modules[@] --module="${1#*=}"; printf "\n"; shift 1;;
724
        -c|--create)
725
          createProject modules[@] --module="${2}"; printf "\n"; shift 2;;
726
        -d=*|--delete=*)
727
          deleteProject --module="${1#*=}"; printf "\n"; shift 1;;
728
        -d|--delete)
729
          deleteProject --module="${2}"; printf "\n"; shift 2;;
730
        -q|--quit)
731
          quitScript; shift 1;;
732
        --log=*|--LOG=*) # already handled; ignore
733
          shift 1;;
734
        --log|--LOG) # already handled; ignore
735
          shift 2;;
736
        --noinfo) # already handled; ignore
737
          shift 1;;
738
        *)
739
          printError "invalid option: $1\n"; shift 1;;
740
      esac
741
    else
742
      otherargs+=("$1")
743
      shift 1
744
    fi
745
  done
746

    
747
  # interactive menu
748
  while ( true ); do
749
    # main menu info prompt and selection
750
    printInfo "QtCreator setup main menu\n"
751
    printf "Please select one of the following actions:\n"
752
    printf "  [C] - create project files\n"
753
    printf "  [D] - delete project files\n"
754
    printf "  [Q] - quit this setup\n"
755
    userinput=""
756
    readUserInput "CcDdQq" userinput
757
    printf "\n"
758

    
759
    # evaluate user selection
760
    case "$userinput" in
761
      C|c)
762
        createProject modules[@]; printf "\n";;
763
      D|d)
764
        deleteProject; printf "\n";;
765
      Q|q)
766
        quitScript;;
767
      *) # sanity check (exit with error)
768
        printError "unexpected argument: $userinput\n";;
769
    esac
770
  done
771

    
772
  exit 0
773
}
774

    
775
################################################################################
776
# SCRIPT ENTRY POINT                                                           #
777
################################################################################
778

    
779
main "$@"