Statistics
| Branch: | Tag: | Revision:

amiro-os / tools / ide / QtCreator / QtCreatorSetup.sh @ 4e8e8462

History | View | Annotate | Download (26.646 KB)

1 e545e620 Thomas Schöpping
################################################################################
2
# AMiRo-OS is an operating system designed for the Autonomous Mini Robot       #
3
# (AMiRo) platform.                                                            #
4 96621a83 Thomas Schöpping
# Copyright (C) 2016..2020  Thomas Schöpping et al.                            #
5 e545e620 Thomas Schöpping
#                                                                              #
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 8516dad6 Thomas Schöpping
# load library
27
source "$(dirname ${BASH_SOURCE[0]})/../../bash/setuplib.sh"
28 e545e620 Thomas Schöpping
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 96621a83 Thomas Schöpping
  printf "# Copyright (c) 2016..2020  Thomas Schöpping                         #\n"
44 e545e620 Thomas Schöpping
  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 4e8e8462 Thomas Schöpping
  printf "usage:    $(basename ${BASH_SOURCE[0]}) [-h|--help] [-p|--project=<module>] [-d|--delete=<module>] [-q|--quit] [--log=<file>]\n"
66 e545e620 Thomas Schöpping
  printf "\n"
67
  printf "options:  -h, --help\n"
68
  printf "              Print this help text.\n"
69 4e8e8462 Thomas Schöpping
  printf "          -p, --project <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>='*')."
73 e545e620 Thomas Schöpping
  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 4e8e8462 Thomas Schöpping
91
  printLog "reading path for project files from user...\n"
92 e545e620 Thomas Schöpping
  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 9cee554d Thomas Schöpping
#            -2
108 cacd990c Thomas Schöpping
#                 Error: include directory could not be resolved.
109 e545e620 Thomas Schöpping
#
110
function retrieveGccIncludeDir {
111
  # retrieve binary path or link
112
  local binpath=$(which arm-none-eabi-gcc)
113 9cee554d Thomas Schöpping
  local gccincpath=""
114 e545e620 Thomas Schöpping
  if [ -z "$binpath" ]; then
115
    printError "command 'arm-none-eabi-gcc' not found\n"
116
    return -1
117
  else 
118
119
    # traverse any links
120
    while [ -L "$binpath" ]; do
121 680d05e5 Thomas Schöpping
      binpath=$(realpath $(dirname $binpath)/$(readlink $binpath))
122 e545e620 Thomas Schöpping
    done
123
    printInfo "gcc-arm-none-eabi detected: $binpath\n"
124
125
    # return include path
126 9cee554d Thomas Schöpping
    gccincpath=$(realpath $(dirname ${binpath})/../arm-none-eabi/include/)
127
    if [ ! -d "$gccincpath" ]; then
128
      printWarning "$gccincpath does not exist\n"
129
      return -2
130
    else
131
      eval $1="$gccincpath"
132
      return 0
133
    fi
134 e545e620 Thomas Schöpping
  fi
135
}
136
137 959f302e Thomas Schöpping
### detect available modules ###################################################
138
# Detect all avalable modules supported by AMiRo-OS.
139 e545e620 Thomas Schöpping
#
140 959f302e Thomas Schöpping
# usage:      detectModules <modulearray>
141
# arguments:  <modulearray>
142
#                 Array variable to store all detected modules to.
143
# return:     n/a
144
#
145
function detectModules {
146
  local modulesdir=$(realpath $(dirname $(realpath ${BASH_SOURCE[0]}))/../../../modules)
147
  local modules_detected=()
148 e545e620 Thomas Schöpping
149 959f302e Thomas Schöpping
  # detect all available modules (via directories)
150
  for dir in $(ls -d ${modulesdir}/*/); do
151
    modules_detected[${#modules_detected[@]}]=$(basename $dir)
152 e545e620 Thomas Schöpping
  done
153
154 959f302e Thomas Schöpping
  # set the output variable
155
  eval "$1=(${modules_detected[*]})"
156 e545e620 Thomas Schöpping
}
157
158 4e8e8462 Thomas Schöpping
### create project files for a single or all modules ###########################
159
# Create project files for a single or all modules.
160 e545e620 Thomas Schöpping
#
161 4e8e8462 Thomas Schöpping
# usage:      createProject <modules> [-m|--module=<module>] [-p|--path=<path>] [--gcc=<path>] [-o|--out=<var>] [--gccout=<var>]
162 959f302e Thomas Schöpping
# arguments:  <modules>
163
#                 Array containing all modules available.
164
#             -m, --module <module>
165 4e8e8462 Thomas Schöpping
#                 Name (folder name) of the module for which project files shall be generated, or '*' to generate for all modules.
166 959f302e Thomas Schöpping
#             -p, --path <path>
167 e545e620 Thomas Schöpping
#                 Path where to create the project files.
168
#             --gcc=<path>
169
#                 Path to the GCC include directory.
170
#             -o, --out <var>
171
#                 Variable to store the path to.
172
#             --gccout=<var>
173
#                 Variable to store the path to the GCC include directory to.
174 959f302e Thomas Schöpping
#                 If this optional arguments is absent, ths function will ask for user input.
175 e545e620 Thomas Schöpping
# return:     0
176
#                 No error or warning occurred.
177 959f302e Thomas Schöpping
#             1
178
#                 Aborted by user.
179
#             -1
180
#                 No modules available.
181
#             -2
182
#                 The specified <module> could not be found.
183
#             -3
184
#                 Parsing the project for the specified module failed.
185 57cbd1cd Thomas Schöpping
#             -4
186
#                 Missing dependencies.
187 e545e620 Thomas Schöpping
#
188 4e8e8462 Thomas Schöpping
function createProject {
189 e545e620 Thomas Schöpping
  local userdir=$(pwd)
190 959f302e Thomas Schöpping
  local modulesdir=$(realpath $(dirname $(realpath ${BASH_SOURCE[0]}))/../../../modules)
191
  local modules=("${!1}")
192
  local module=""
193 e545e620 Thomas Schöpping
  local projectdir=""
194
  local gccincludedir=""
195
  local outvar=""
196
  local gccoutvar=""
197 4e8e8462 Thomas Schöpping
  local modules2generate=()
198 e545e620 Thomas Schöpping
199 57cbd1cd Thomas Schöpping
  # check dependencies
200
  checkCommands make
201
  if [ $? -ne 0 ]; then
202
    printError "Missing dependencies detected.\n"
203
    return -4
204
  fi
205
206 e545e620 Thomas Schöpping
  # parse arguments
207
  local otherargs=()
208
  while [ $# -gt 0 ]; do
209
    if ( parseIsOption $1 ); then
210
      case "$1" in
211 959f302e Thomas Schöpping
        -m=*|--module=*)
212
          module="${1#*=}"; shift 1;;
213
        -m|--module)
214
          module="$2"; shift 2;;
215 e545e620 Thomas Schöpping
        -p=*|--path=*)
216
          projectdir=$(realpath "${1#*=}"); shift 1;;
217
        -p|--path)
218
          projectdir=$(realpath "$2"); shift 2;;
219
        --gcc=*)
220
          gccincludedir=$(realpath "${1#*=}"); shift 1;;
221
        --gcc)
222
          gccincludedir=$(realpath "$2"); shift 2;;
223
        -o=*|--out=*)
224
          outvar=${1#*=}; shift 1;;
225
        -o|--out)
226
          outvar=$2; shift 2;;
227
        --gccout=*)
228
          gccoutvar=$(realpath "${1#*=}"); shift 1;;
229
        --gccout)
230
          gccoutvar=$(realpath "$2"); shift 2;;
231
        *)
232
          printError "invalid option: $1\n"; shift 1;;
233
      esac
234
    else
235
      otherargs+=("$1")
236
      shift 1
237
    fi
238
  done
239
240 959f302e Thomas Schöpping
  # sanity check for the modules variable
241
  if [ -z "${modules[*]}" ]; then
242
    printError "no modules available\n"
243
    return -1
244
  fi
245
246
  # select module
247
  if [ -z $module ]; then
248
    # list all available modules
249 4e8e8462 Thomas Schöpping
    printInfo "select a module, type '*' for all or type 'A' to abort:\n"
250 959f302e Thomas Schöpping
    for (( idx=0; idx<${#modules[@]}; ++idx )); do
251
      printf "%4u: %s\n" $(($idx + 1)) "${modules[$idx]}"
252
    done
253
    # read user input
254
    printLog "read user selection\n"
255
    local userinput=""
256 4e8e8462 Thomas Schöpping
    while [[ ! "$userinput" =~ ^[0-9]+$ ]] || [ ! "$userinput" -gt 0 ] || [ ! "$userinput" -le ${#modules[@]} ] && [[ ! "$userinput" =~ ^(\*|[Aa])$ ]]; do
257 959f302e Thomas Schöpping
      read -p "your selection: " -e userinput
258
      printLog "user selection: $userinput\n"
259 4e8e8462 Thomas Schöpping
      if [[ ! "$userinput" =~ ^[0-9]+$ ]] || [ ! "$userinput" -gt 0 ] || [ ! "$userinput" -le ${#modules[@]} ] && [[ ! "$userinput" =~ ^(\*|[Aa])$ ]]; then
260
        printWarning "Please enter an integer between 1 and ${#modules[@]}, '*' to select all or 'A' to abort.\n"
261 959f302e Thomas Schöpping
      fi
262
    done
263 4e8e8462 Thomas Schöpping
    if [[ "$userinput" =~ ^[0-9]+$ ]]; then
264
      # store selection
265
      modules2generate=(${modules[$(($userinput - 1))]})
266
    elif [[ "$userinput" =~ ^\*$ ]]; then
267
      modules2generate=(${modules[@]})
268
    elif [[ "$userinput" =~ ^[Aa]$ ]]; then
269 959f302e Thomas Schöpping
      printWarning "aborted by user\n"
270
      return 1
271
    fi
272
    printf "\n"
273
  else
274 4e8e8462 Thomas Schöpping
    # check whether the specified module is available
275
    if [[ ! "${modules[@]}" =~ "$module" ]]; then
276
      printError "module '$module' not available\n"
277 959f302e Thomas Schöpping
      return -2
278 4e8e8462 Thomas Schöpping
    else
279
      modules2generate=($module)
280 959f302e Thomas Schöpping
    fi
281
  fi
282 e545e620 Thomas Schöpping
283
  # read absolute project directory if required
284
  if [ -z "$projectdir" ]; then
285
    getProjectDir projectdir
286 959f302e Thomas Schöpping
    printf "\n"
287
  fi
288
289
  # check for existing project files
290 4e8e8462 Thomas Schöpping
  local projectfiles=()
291
  for module in ${modules2generate[@]}; do
292
    projectfiles+=($(find ${projectdir} -maxdepth 1 -type f -regextype posix-extended -regex "^.*/${module}\.(includes|files|config|creator)$" | sort))
293
  done
294 df5aa9b6 Thomas Schöpping
  if [ ${#projectfiles[@]} != 0 ]; then
295 959f302e Thomas Schöpping
    printWarning "The following files will be overwritten:\n"
296 23230307 Thomas Schöpping
    for pfile in ${projectfiles[@]}; do
297
      printWarning "\t$(basename $pfile)\n"
298
    done
299 959f302e Thomas Schöpping
    local userinput=""
300
    printInfo "Continue and overwrite? [y/n]\n"
301
    readUserInput "YyNn" userinput
302
    case "$userinput" in
303
      Y|y)
304
        ;;
305
      N|n)
306 4e8e8462 Thomas Schöpping
        printWarning "project generation aborted by user\n"
307 959f302e Thomas Schöpping
        return 1
308
        ;;
309
      *)
310
        printError "unexpected input: ${userinput}\n"; return -999;;
311
    esac
312
    printf "\n"
313 e545e620 Thomas Schöpping
  fi
314
315 959f302e Thomas Schöpping
  # retrieve absolute GCC include path
316 e545e620 Thomas Schöpping
  if [ -z "$gccincludedir" ]; then
317
    retrieveGccIncludeDir gccincludedir
318
  fi
319
320 4e8e8462 Thomas Schöpping
  # generate all modules
321
  for module in ${modules2generate[@]}; do
322
    # print message
323
    printInfo "generating QtCreator project files for the $module module...\n"
324
325
    # change to project directory
326
    cd "$projectdir"
327
328
    # run make, but only run the GCC preprocessor and produce no binaries
329
    local sourcefiles=()
330
    local sourcefile=""
331
    local parse_state="WAIT_FOR_INCLUDE_COMPILE_MAKE"
332
    local makedir=""
333
    local makedirs=()
334
    local quotes="\'\"\´\`\„\“"
335
    # capture all output from make and GCC and append the return value of make as last line
336
    printInfo "processing project (this may take a while)...\n"
337
    local rawout=$(make --directory ${modulesdir}/${module} --always-make USE_OPT="-v -E -H" USE_VERBOSE_COMPILE="no" OUTFILES="" 2>&1 && echo $?)
338
    # check whether the make call was successfull
339
    if [[ $(echo "${rawout}" | tail -n 1) != "0" ]]; then
340
      printError "executing 'make' in module directory failed\n"
341
      cd "$userdir"
342
      return -3
343
    else
344
      # cleanup
345
      make --directory ${modulesdir}/${module} clean &>/dev/null
346
    fi
347
    # extract file names from raw output
348
    IFS=$'\n'; rawout=($rawout); unset IFS
349
    for line in "${rawout[@]}"; do
350
      case $parse_state in
351
        WAIT_FOR_INCLUDE_COMPILE_MAKE)
352
          # lines stating include files look like:
353
          # ... <../relative/path/to/file>
354
          if [[ "$line" =~ ^\.+[[:blank:]].+\..+$ ]]; then
355
            sourcefile=${line##* }
356
            if [[ ! "$sourcefile" =~ ^/ ]]; then
357
              sourcefile=$(realpath ${makedirs[-1]}/${sourcefile})
358
            fi
359
            sourcefiles[${#sourcefiles[@]}]="$sourcefile"
360
          # whenever the next source file is processed, a message appears like:
361
          # Compiling <filename>
362
          elif [[ "$line" =~ ^Compiling[[:blank:]](.+\..+)$ ]]; then
363
            printf "."
364
            sourcefile=${BASH_REMATCH[1]}
365
            parse_state="WAIT_FOR_COMPILERCALL"
366
          # if make is called again in another directory or a nested make call leaves the directory, a message appears like:
367
          # make[1]: Entering directory 'directory'
368
          # make[999]: Verzeichnis „directory“ wird verlassen
369
          elif [[ "$line" =~ ^make(\[[0-9]+\])?:([[:alnum:]]|[[:blank:]])*[$quotes].*[$quotes]([[:alnum:]]|[[:blank:]])*$ ]]; then
370
            # extract directory path
371
            makedir=$(echo ${line} | grep -oE "[${quotes}].*[${quotes}]" | grep -oE "[^${quotes}].*[^${quotes}]")
372
            # if the makedirs stack is empty or the directory does not mathc the last entry
373
            if [ ${#makedirs[@]} == 0 ] || [ "${makedir}" != "${makedirs[-1]}" ]; then
374
              # push the directory to the stack
375
              makedirs+=(${makedir})
376
            else
377
              # pop the directory from the stack
378
              unset makedirs[-1]
379
            fi
380
          fi;;
381
        WAIT_FOR_COMPILERCALL)
382
          # wait for the actual call of the compiler to retrieve the full path to the source file
383
          if [[ "$line" == *${sourcefile}* ]]; then
384
            line="${line%%${sourcefile}*}${sourcefile}"
385
            line="${line##* }"
386
            if [[ "$line" =~ ^/ ]]; then
387
              # aboslute path
388
              sourcefile=$line
389
            else
390
              # relative path
391
              sourcefile=$(realpath ${makedirs[-1]}/${line##* })
392
            fi
393
            sourcefiles[${#sourcefiles[@]}]="$sourcefile"
394
            parse_state="WAIT_FOR_INCLUDE_COMPILE_MAKE"
395
          fi;;
396
      esac
397
    done
398
    unset rawout
399
    printf "\n"
400
    # sort and remove duplicates
401
    IFS=$'\n'; sourcefiles=($(sort --unique <<< "${sourcefiles[*]}")); unset IFS
402 959f302e Thomas Schöpping
403 4e8e8462 Thomas Schöpping
    # extract include paths
404
    local includes=()
405
    for source in ${sourcefiles[*]}; do
406
      includes[${#includes[@]}]="$(dirname ${source})"
407
    done
408
    # sort and remove duplicates
409
    IFS=$'\n'; includes=($(sort --unique <<< "${includes[*]}")); unset IFS
410 959f302e Thomas Schöpping
411 4e8e8462 Thomas Schöpping
    # generate the .incldues file, containing all include paths
412
    echo "" > ${projectdir}/${module}.includes
413
    for inc in ${includes[*]}; do
414
      echo "$inc" >> ${projectdir}/${module}.includes
415
    done
416
    # generate the .files file, containing all source files
417
    echo "" > ${projectdir}/${module}.files
418
    for source in ${sourcefiles[*]}; do
419
      # skip GCC files
420
      if [[ ! "$source" =~ .*/gcc.* ]]; then
421
        echo "$source" >> ${projectdir}/${module}.files
422
      fi
423
    done
424
    # generate a default project configuration file if it doesn't exist yet
425
    if [ ! -f ${projectdir}/${module}.config ]; then
426
      echo "// Add predefined macros for your project here. For example:" > ${projectdir}/${module}.config
427
      echo "// #define YOUR_CONFIGURATION belongs here" >> ${projectdir}/${module}.config
428
    fi
429
    # generate a default .creator file if it doesn't exist yet
430
    if [ ! -f ${projectdir}/${module}.creator ]; then
431
      echo "[general]" > ${projectdir}/${module}.creator
432 959f302e Thomas Schöpping
    fi
433 e545e620 Thomas Schöpping
434 4e8e8462 Thomas Schöpping
    # go back to user directory
435
    cd $userdir
436
  done
437 e545e620 Thomas Schöpping
438
  # fill the output variables
439
  if [ ! -z "$outvar" ]; then
440
    eval $outvar="$projectdir"
441
  fi
442
  if [ ! -z "$gccoutvar" ]; then
443
    eval $gccoutvar="$gccincludedir"
444
  fi
445
446
  return 0
447
}
448
449 4e8e8462 Thomas Schöpping
### delete project files for a single or all modules ###########################
450 959f302e Thomas Schöpping
# Deletes all project files and optionally .user files, too.
451 e545e620 Thomas Schöpping
#
452 4e8e8462 Thomas Schöpping
# usage:      deleteProject [-p|--path=<path>] [-m|--module=<module>] [-o|--out=<var>] [-w|--wipe=<flag>]
453 e545e620 Thomas Schöpping
# arguments:  -p, --path <path>
454 959f302e Thomas Schöpping
#                 Path where to delete the project files.
455
#             -m, --module <module>
456 4e8e8462 Thomas Schöpping
#                 Module name for which the project files shall be deleted or '*' delete for all projects.
457 e545e620 Thomas Schöpping
#             -o, --out <var>
458
#                 Variable to store the path to.
459 4e8e8462 Thomas Schöpping
#             -w, --wipe <flag>
460
#                 Flag whether to delete .user files as well (must be either "true" or "false").
461
# return:     0
462
#               No error or warning occurred.
463
#             1
464
#               Aborted by user.
465
#             2
466
#               There is no project files (for the specified module) at the specified location.
467 e545e620 Thomas Schöpping
#
468 4e8e8462 Thomas Schöpping
function deleteProject {
469
  local module=""
470
  local modules=()
471 e545e620 Thomas Schöpping
  local projectdir=""
472
  local outvar=""
473 4e8e8462 Thomas Schöpping
  local wipe=""
474
  local modules2delete=()
475 df5aa9b6 Thomas Schöpping
  local files=()
476 4e8e8462 Thomas Schöpping
  local userinput=""
477 e545e620 Thomas Schöpping
478
  # parse arguments
479
  local otherargs=()
480
  while [ $# -gt 0 ]; do
481
    if ( parseIsOption $1 ); then
482
      case "$1" in
483
        -p=*|--path=*)
484
          projectdir=$(realpath "${1#*=}"); shift 1;;
485
        -p|--path)
486
          projectdir=$(realpath "$2"); shift 2;;
487 959f302e Thomas Schöpping
        -m=*|--module=*)
488 4e8e8462 Thomas Schöpping
          module="${1#*=}"; shift 1;;
489 959f302e Thomas Schöpping
        -m|--module)
490 4e8e8462 Thomas Schöpping
          module="${2}"; shift 2;;
491 e545e620 Thomas Schöpping
        -o=*|--out=*)
492
          outvar=${1#*=}; shift 1;;
493
        -o|--out)
494
          outvar=$2; shift 2;;
495 4e8e8462 Thomas Schöpping
        -w=*|--wipe=*)
496
          wipe="${1#*=}"; shift 1;;
497 959f302e Thomas Schöpping
        -w|--wipe)
498 4e8e8462 Thomas Schöpping
          wipe="$2"; shift 2;;
499 e545e620 Thomas Schöpping
        *)
500
          printError "invalid option: $1\n"; shift 1;;
501
      esac
502
    else
503
      otherargs+=("$1")
504
      shift 1
505
    fi
506
  done
507
508 4e8e8462 Thomas Schöpping
  # sanity checks on parameters
509
  if [ ! -z $wipe ] && [[ ! "$wipe" =~ "(true|false)" ]]; then
510
    printWarning "invalid value set to 'wipe' argument\n"
511
    printInfo "I will act as if there was no --wipe argument and ask for input later.\n"
512
    wipe=""
513
  fi
514
515 e545e620 Thomas Schöpping
  # read absolute project directory if required
516
  if [ -z "$projectdir" ]; then
517
    getProjectDir projectdir
518 4e8e8462 Thomas Schöpping
    printf "\n"
519 e545e620 Thomas Schöpping
  fi
520
521 4e8e8462 Thomas Schöpping
  # retrieve all modules in the specified directory
522
  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))
523
524
  # check whether there are any project files at the specified location
525
  if [ ${#modules[@]} -eq 0 ]; then
526
    printWarning "no projects detected at '${projectdir}'\n"
527
    return 2
528
  fi
529
530
  # select module
531
  if [ -z "$module" ]; then
532
    # list all available modules
533
    printInfo "select a module, type '*' for all or type 'A' to abort:\n"
534
    for (( idx=0; idx<${#modules[@]}; ++idx )); do
535
      printf "%4u: %s\n" $(($idx + 1)) "${modules[$idx]}"
536
    done
537
    # read user input
538
    printLog "read user selection\n"
539
    userinput=""
540
    while [[ ! "$userinput" =~ ^[0-9]+$ ]] || [ ! "$userinput" -gt 0 ] || [ ! "$userinput" -le ${#modules[@]} ] && [[ ! "$userinput" =~ ^(\*|[Aa])$ ]]; do
541
      read -p "your selection: " -e userinput
542
      printLog "user selection: $userinput\n"
543
      if [[ ! "$userinput" =~ ^[0-9]+$ ]] || [ ! "$userinput" -gt 0 ] || [ ! "$userinput" -le ${#modules[@]} ] && [[ ! "$userinput" =~ ^(\*|[Aa])$ ]]; then
544
        printWarning "Please enter an integer between 1 and ${#modules[@]}, '*' to select all or 'A' to abort.\n"
545
      fi
546
    done
547
    if [[ "$userinput" =~ ^[0-9]+$ ]]; then
548
      # store selection
549
      modules2delete=(${modules[$(($userinput - 1))]})
550
    elif [[ "$userinput" =~ ^\*$ ]]; then
551
      modules2delete=(${modules[@]})
552
    elif [[ "$userinput" =~ ^[Aa]$ ]]; then
553
      printWarning "aborted by user\n"
554
      return 1
555 959f302e Thomas Schöpping
    fi
556 4e8e8462 Thomas Schöpping
    printf "\n"
557 959f302e Thomas Schöpping
  else
558 4e8e8462 Thomas Schöpping
    # check whether the specified module is available
559
    if [[ ! "${modules[@]}" =~ "$module" ]]; then
560
      printWarning "there are no project files for module '$module' at location '$projectdir'\n"
561
      return 2
562 959f302e Thomas Schöpping
    else
563 4e8e8462 Thomas Schöpping
      modules2delete=($module)
564 959f302e Thomas Schöpping
    fi
565 e545e620 Thomas Schöpping
  fi
566 4e8e8462 Thomas Schöpping
567
  # retrieve all files
568
  for module in ${modules2delete[@]}; do
569
    files+=($(find "${projectdir}" -maxdepth 1 -type f -regextype posix-extended -regex "^.*${module}\.(includes|files|config|creator|cflags|cxxflags|creator\.user(\..+)?)$"))
570
  done
571
572
  # read wipe information if required
573
  if [[ "${files[@]}" =~ ^.+\.creator\.user(\..+)?$ ]] &&  [ -z "$wipe" ]; then
574
    userinput=""
575
    printInfo "Wipe user data as well? [y/n]\n"
576
    readUserInput "YyNn" userinput
577
    case "$userinput" in
578
      Y|y)
579
        wipe="true";;
580
      N|n)
581
        wipe="false";;
582
      *)
583
        printError "unexpected input: ${userinput}\n"; return -999;;
584
    esac
585
    printf "\n"
586
  fi
587
588
  # remove .user files if required
589
  if [ ! "$wipe" = "true" ]; then
590
    files=()
591
    for module in ${modules2delete[@]}; do
592
      files+=($(find "${projectdir}" -maxdepth 1 -type f -regextype posix-extended -regex "^.*${module}\.(includes|files|config|creator|cflags|cxxflags)$"))
593
    done
594
  fi
595
596
  # list all files to be deleted and ask for confirmation
597
  if [ ${#files[@]} -gt 0 ]; then
598
    printInfo "The following files will be deleted:\n"
599 df5aa9b6 Thomas Schöpping
    for file in ${files[@]}; do
600
      printInfo "\t$(basename ${file})\n"
601
    done
602 4e8e8462 Thomas Schöpping
    userinput=""
603
    printInfo "Do you want to continue? [y/n]\n"
604
    readUserInput "YyNn" userinput
605
    case "$userinput" in
606
      Y|y)
607
        ;;
608
      N|n)
609
        printWarning "aborted by user\n"
610
        return 1;;
611
      *)
612
        printError "unexpected input: ${userinput}\n"; return -999;;
613
    esac
614 959f302e Thomas Schöpping
  else
615 4e8e8462 Thomas Schöpping
    printInfo "No files to delete.\n"
616 e545e620 Thomas Schöpping
  fi
617
618 4e8e8462 Thomas Schöpping
  # finally delete the files
619
  for file in ${files[@]}; do
620
    rm ${file} 2>&1 | tee -a $LOG_FILE
621
  done
622
623 959f302e Thomas Schöpping
  # store the path to the output variable, if required
624 e545e620 Thomas Schöpping
  if [ ! -z "$outvar" ]; then
625
    eval $outvar="$projectdir"
626
  fi
627
628
  return 0
629
}
630
631
### main function of this script ###############################################
632 cacd990c Thomas Schöpping
# Creates, deletes and wipes QtCreator project files for any module supported by AMiRo-OS.
633 e545e620 Thomas Schöpping
#
634
# usage:      see function printHelp
635
# arguments:  see function printHelp
636
# return:     0
637
#                 No error or warning ocurred.
638
#
639
function main {
640
# print welcome/info text if not suppressed
641
  if [[ $@ != *"--noinfo"* ]]; then
642
    printWelcomeText
643
  else
644
    printf "######################################################################\n"
645
  fi
646
  printf "\n"
647
648
  # if --help or -h was specified, print the help text and exit
649
  if [[ $@ == *"--help"* || $@ == *"-h"* ]]; then
650
    printHelp
651
    printf "\n"
652
    quitScript
653
  fi
654
655
  # set log file if specified
656
  if [[ $@ == *"--log"* ]] || [[ $@ == *"--LOG"* ]]; then
657
    # get the parameter (file name)
658
    local cmdidx=1
659
    while [[ ! "${!cmdidx}" = "--log"* ]] && [[ ! "${!cmdidx}" = "--LOG"* ]]; do
660
      cmdidx=$[cmdidx + 1]
661
    done
662
    local cmd="${!cmdidx}"
663
    local logfile=""
664
    if [[ "$cmd" = "--log="* ]] || [[ "$cmd" = "--LOG="* ]]; then
665
      logfile=${cmd#*=}
666
    else
667
      local filenameidx=$((cmdidx + 1))
668
      logfile="${!filenameidx}"
669
    fi
670
    # optionally force silent appending
671
    if [[ "$cmd" = "--LOG"* ]]; then
672
      setLogFile --option=c --quiet "$logfile" LOG_FILE
673
    else
674
      setLogFile "$logfile" LOG_FILE
675
      printf "\n"
676
    fi
677
  fi
678
  # log script name
679
  printLog "this is $(realpath ${BASH_SOURCE[0]})\n"
680
681 959f302e Thomas Schöpping
  # detect available modules and inform user
682
  local modules=()
683
  detectModules modules
684
  case "${#modules[@]}" in
685
    0)
686
      printInfo "no module has been detected\n";;
687
    1)
688
      printInfo "1 module has been detected:\n";;
689
    *)
690
      printInfo "${#modules[@]} modules have been detected:\n"
691
  esac
692
  for (( idx=0; idx<${#modules[@]}; ++idx )); do
693
    printInfo "  - ${modules[$idx]}\n"
694
  done
695
  printf "\n"
696
697 e545e620 Thomas Schöpping
  # parse arguments
698
  local otherargs=()
699
  while [ $# -gt 0 ]; do
700
    if ( parseIsOption $1 ); then
701
      case "$1" in
702
        -h|--help) # already handled; ignore
703
          shift 1;;
704 4e8e8462 Thomas Schöpping
        -p=*|--project=*)
705
          createProject modules[@] --module="${1#*=}"; printf "\n"; shift 1;;
706
        -p|--project)
707
          createProject modules[@] --module="${2}"; printf "\n"; shift 2;;
708
        -d=*|--delete=*)
709
          deleteProject --module="${1#*=}"; printf "\n"; shift 1;;
710
        -d|--delete)
711
          deleteProject --module="${2}"; printf "\n"; shift 2;;
712 e545e620 Thomas Schöpping
        -q|--quit)
713
          quitScript; shift 1;;
714
        --log=*|--LOG=*) # already handled; ignore
715
          shift 1;;
716
        --log|--LOG) # already handled; ignore
717
          shift 2;;
718
        --noinfo) # already handled; ignore
719
          shift 1;;
720
        *)
721
          printError "invalid option: $1\n"; shift 1;;
722
      esac
723
    else
724
      otherargs+=("$1")
725
      shift 1
726
    fi
727
  done
728
729
  # interactive menu
730
  while ( true ); do
731
    # main menu info prompt and selection
732
    printInfo "QtCreator setup main menu\n"
733
    printf "Please select one of the following actions:\n"
734 4e8e8462 Thomas Schöpping
    printf "  [P] - create project files\n"
735
    printf "  [D] - delete project files\n"
736 e545e620 Thomas Schöpping
    printf "  [Q] - quit this setup\n"
737
    local userinput=""
738 4e8e8462 Thomas Schöpping
    readUserInput "PpDdQq" userinput
739 e545e620 Thomas Schöpping
    printf "\n"
740
741
    # evaluate user selection
742
    case "$userinput" in
743 4e8e8462 Thomas Schöpping
      P|p)
744
        createProject modules[@]; printf "\n";;
745
      D|d)
746
        deleteProject; printf "\n";;
747 e545e620 Thomas Schöpping
      Q|q)
748
        quitScript;;
749
      *) # sanity check (exit with error)
750
        printError "unexpected argument: $userinput\n";;
751
    esac
752
  done
753
754
  exit 0
755
}
756
757
################################################################################
758
# SCRIPT ENTRY POINT                                                           #
759
################################################################################
760
761
main "$@"