Revision 4e8e8462

View differences:

tools/ide/QtCreator/QtCreatorSetup.sh
62 62
#
63 63
function printHelp {
64 64
  printInfo "printing help text\n"
65
  printf "usage:    $(basename ${BASH_SOURCE[0]}) [-h|--help] [-m|--module=<module>] [-a|--all] [-c|--clean] [-w|--wipe] [-q|--quit] [--log=<file>]\n"
65
  printf "usage:    $(basename ${BASH_SOURCE[0]}) [-h|--help] [-p|--project=<module>] [-d|--delete=<module>] [-q|--quit] [--log=<file>]\n"
66 66
  printf "\n"
67 67
  printf "options:  -h, --help\n"
68 68
  printf "              Print this help text.\n"
69
  printf "          -m, --module <module>\n"
70
  printf "              Create project for a single module.\n"
71
  printf "          -a, --all\n"
72
  printf "              Create projects for all modules.\n"
73
  printf "          -c, --clean\n"
74
  printf "              Delete project files.\n"
75
  printf "          -w, --wipe\n"
76
  printf "              Delete project and .user files.\n"
69
  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>='*')."
77 73
  printf "          -q, --quit\n"
78 74
  printf "              Quit the script.\n"
79 75
  printf "          --log=<file>\n"
......
89 85
# return:     n/a
90 86
#
91 87
function getProjectDir {
92
  printLog "reading path for project files from user...\n"
93 88
  local amiroosdir=$(realpath $(dirname $(realpath ${BASH_SOURCE[0]}))/../../../)
94 89
  local input=""
90

  
91
  printLog "reading path for project files from user...\n"
95 92
  read -p "Path where to create/delete project files: " -i $amiroosdir -e input
96 93
  printLog "user selected path $(realpath $input)\n"
97 94
  eval $1="$(realpath $input)"
......
158 155
  eval "$1=(${modules_detected[*]})"
159 156
}
160 157

  
161
### create project files for a single module ###################################
162
# Create project files for a single module.
158
### create project files for a single or all modules ###########################
159
# Create project files for a single or all modules.
163 160
#
164
# usage:      createModuleProject <modules> [-m|--module=<module>] [-p|--path=<path>] [--gcc=<path>] [-o|--out=<var>] [--gccout=<var>]
161
# usage:      createProject <modules> [-m|--module=<module>] [-p|--path=<path>] [--gcc=<path>] [-o|--out=<var>] [--gccout=<var>]
165 162
# arguments:  <modules>
166 163
#                 Array containing all modules available.
167 164
#             -m, --module <module>
168
#                 Name (folder name) of the module for which project files shall be generated.
165
#                 Name (folder name) of the module for which project files shall be generated, or '*' to generate for all modules.
169 166
#             -p, --path <path>
170 167
#                 Path where to create the project files.
171 168
#             --gcc=<path>
......
188 185
#             -4
189 186
#                 Missing dependencies.
190 187
#
191
function createModuleProject {
188
function createProject {
192 189
  local userdir=$(pwd)
193 190
  local modulesdir=$(realpath $(dirname $(realpath ${BASH_SOURCE[0]}))/../../../modules)
194 191
  local modules=("${!1}")
195 192
  local module=""
196
  local moduleidx=""
197 193
  local projectdir=""
198 194
  local gccincludedir=""
199 195
  local outvar=""
200 196
  local gccoutvar=""
197
  local modules2generate=()
201 198

  
202 199
  # check dependencies
203 200
  checkCommands make
......
249 246
  # select module
250 247
  if [ -z $module ]; then
251 248
    # list all available modules
252
    printInfo "choose a module or type 'A' to abort:\n"
249
    printInfo "select a module, type '*' for all or type 'A' to abort:\n"
253 250
    for (( idx=0; idx<${#modules[@]}; ++idx )); do
254 251
      printf "%4u: %s\n" $(($idx + 1)) "${modules[$idx]}"
255 252
    done
256 253
    # read user input
257 254
    printLog "read user selection\n"
258 255
    local userinput=""
259
    while [[ ! "$userinput" =~ ^[0-9]+$ ]] || [ ! "$userinput" -gt 0 ] || [ ! "$userinput" -le ${#modules[@]} ] && [[ ! "$userinput" =~ ^[Aa]$ ]]; do
256
    while [[ ! "$userinput" =~ ^[0-9]+$ ]] || [ ! "$userinput" -gt 0 ] || [ ! "$userinput" -le ${#modules[@]} ] && [[ ! "$userinput" =~ ^(\*|[Aa])$ ]]; do
260 257
      read -p "your selection: " -e userinput
261 258
      printLog "user selection: $userinput\n"
262
      if [[ ! "$userinput" =~ ^[0-9]+$ ]] || [ ! "$userinput" -gt 0 ] || [ ! "$userinput" -le ${#modules[@]} ] && [[ ! "$userinput" =~ ^[Aa]$ ]]; then
263
        printWarning "Please enter an integer between 1 and ${#modules[@]} or 'A' to abort.\n"
259
      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"
264 261
      fi
265 262
    done
266
    if [[ "$userinput" =~ ^[Aa]$ ]]; then
263
    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
267 269
      printWarning "aborted by user\n"
268 270
      return 1
269 271
    fi
270
    # store selection
271
    moduleidx=$(($userinput - 1))
272
    module="${modules[$moduleidx]}"
273 272
    printf "\n"
274 273
  else
275
    # search all modules for the selected one
276
    for (( idx=0; idx<${#modules[@]}; ++idx )); do
277
      if [ "${modules[$idx]}" = "$module" ]; then
278
        moduleidx=$idx
279
        break
280
      fi
281
    done
282
    # error if the module could not be found
283
    if [ -z $moduleidx ]; then
284
      printError "module ($module) not available\n"
274
    # check whether the specified module is available
275
    if [[ ! "${modules[@]}" =~ "$module" ]]; then
276
      printError "module '$module' not available\n"
285 277
      return -2
278
    else
279
      modules2generate=($module)
286 280
    fi
287 281
  fi
288 282

  
......
293 287
  fi
294 288

  
295 289
  # check for existing project files
296
  local projectfiles=($(find ${projectdir} -maxdepth 1 -type f | grep -E "${module}\.(includes|files|config|creator)$"))
290
  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
297 294
  if [ ${#projectfiles[@]} != 0 ]; then
298 295
    printWarning "The following files will be overwritten:\n"
299 296
    for pfile in ${projectfiles[@]}; do
......
306 303
      Y|y)
307 304
        ;;
308 305
      N|n)
309
        printWarning "Project generation for ${module} module aborted by user\n"
306
        printWarning "project generation aborted by user\n"
310 307
        return 1
311 308
        ;;
312 309
      *)
......
315 312
    printf "\n"
316 313
  fi
317 314

  
318
  # print message
319
  printInfo "generating QtCreator project files for the $module module...\n"
320

  
321 315
  # retrieve absolute GCC include path
322 316
  if [ -z "$gccincludedir" ]; then
323 317
    retrieveGccIncludeDir gccincludedir
324 318
  fi
325 319

  
326
  # change to project directory
327
  cd "$projectdir"
328

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

  
404
  # extract include paths
405
  local includes=()
406
  for source in ${sourcefiles[*]}; do
407
    includes[${#includes[@]}]="$(dirname ${source})"
408
  done
409
  # sort and remove duplicates
410
  IFS=$'\n'; includes=($(sort --unique <<< "${includes[*]}")); unset IFS
403
    # 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
411 410

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

  
435
  # go back to user directory
436
  cd $userdir
434
    # go back to user directory
435
    cd $userdir
436
  done
437 437

  
438 438
  # fill the output variables
439 439
  if [ ! -z "$outvar" ]; then
......
446 446
  return 0
447 447
}
448 448

  
449
### create project files for all modules #######################################
450
# Create project files for all modules.
451
#
452
# usage:      createAllProjects <modules> [-p|--path=<path>] [--gcc=<path>] [-o|--out=<var>] [--gccout=<var>]
453
# arguments:  <modules>
454
#                 Array containing all modules available.
455
#             -p, --path <path>
456
#                 Path where to create the project files.
457
#             --gcc=<path>
458
#                 Path to the GCC include directory.
459
#             -o, --out <var>
460
#                 Variable to store the path to.
461
#             --gccout=<var>
462
#                 Variable to store the path to the GCC include directory to.
463
#                 If this optional arguments is absent, ths function will ask for user input.
464
# return:     0
465
#                 No error or warning occurred.
466
#             1
467
#                 Aborted by user.
468
#             -1
469
#                 No modules available.
470
#
471
function createAllProjects {
472
  local modules=("${!1}")
473
  local projectsdir=""
474
  local gccincludedir=""
475
  local outvar=""
476
  local gccoutvar=""
477

  
478
  # parse arguments
479
  local otherargs=()
480
  while [ $# -gt 0 ]; do
481
    if ( parseIsOption $1 ); then
482
      case "$1" in
483
        -p=*|--path=*)
484
          projectsdir=$(realpath "${1#*=}"); shift 1;;
485
        -p|--path)
486
          projectsdir=$(realpath "$2"); shift 2;;
487
        --gcc=*)
488
          gccincludedir=$(realpath "${1#*=}"); shift 1;;
489
        --gcc)
490
          gccincludedir=$(realpath "$2"); shift 2;;
491
        -o=*|--out=*)
492
          outvar=${1#*=}; shift 1;;
493
        -o|--out)
494
          outvar=$2; shift 2;;
495
        --gccout=*)
496
          gccoutvar=$(realpath "${1#*=}"); shift 1;;
497
        --gccout)
498
          gccoutvar=$(realpath "$2"); shift 2;;
499
        *)
500
          printError "invalid option: $1\n"; shift 1;;
501
      esac
502
    else
503
      otherargs+=("$1")
504
      shift 1
505
    fi
506
  done
507

  
508
  # sanity check for the modules variable
509
  if [ -z "${modules[*]}" ]; then
510
    printError "no modules available\n"
511
    return -1
512
  fi
513

  
514
  # read absolute project directory if required
515
  if [ -z "$projectsdir" ]; then
516
    getProjectDir projectsdir
517
  fi
518

  
519
  # check for existing project files
520
  local projectfiles=()
521
  for module in ${modules[@]}; do
522
    projectfiles+=($(find ${projectsdir} -maxdepth 1 -type f | grep -E "${module}\.(includes|files|config|creator)$"))
523
  done
524
  if [ ${#projectfiles[@]} != 0 ]; then
525
    printWarning "The following files will be removed:\n"
526
    for pfile in ${projectfiles[@]}; do
527
      printWarning "\t$(basename $pfile)\n"
528
    done
529
    local userinput=""
530
    printInfo "Continue and overwrite? [y/n]\n"
531
    readUserInput "YyNn" userinput
532
    case "${userinput}" in
533
      Y|y)
534
        for pfile in ${projectfiles[*]}; do
535
          rm "$pfile" 2>&1 | tee -a $LOG_FILE
536
        done
537
        ;;
538
      N|n)
539
        printWarning "Project generation aborted by user\n"
540
        return 1
541
        ;;
542
      *)
543
        printError "unexpected input: ${userinput}\n"
544
        return 999
545
        ;;
546
    esac
547
  fi
548

  
549
  # print message
550
  printf "\n"
551
  printInfo "generating QtCreator project files for all modules...\n"
552

  
553
  # retrieve absolute GCC include path
554
  if [ -z "$gccincludedir" ]; then
555
    retrieveGccIncludeDir gccincludedir
556
  fi
557

  
558
  # iterate over all modules
559
  local retval=1
560
  for module in ${modules[@]}; do
561
    if [ $retval != 0 ]; then
562
      printf "\n"
563
    fi
564
    createModuleProject modules[@] --module="$module" --path="$projectsdir" --gcc="$gccincludedir"
565
    retval=$?
566
  done
567

  
568
  return 0
569
}
570

  
571
### delete project files #######################################################
449
### delete project files for a single or all modules ###########################
572 450
# Deletes all project files and optionally .user files, too.
573 451
#
574
# usage:      deleteProjects [-p|--path=<path>] [-m|--module=<module>] [-o|--out=<var>] [-w|-wipe]
452
# usage:      deleteProject [-p|--path=<path>] [-m|--module=<module>] [-o|--out=<var>] [-w|--wipe=<flag>]
575 453
# arguments:  -p, --path <path>
576 454
#                 Path where to delete the project files.
577 455
#             -m, --module <module>
578
#                 Module name for which the project files shall be deleted.
456
#                 Module name for which the project files shall be deleted or '*' delete for all projects.
579 457
#             -o, --out <var>
580 458
#                 Variable to store the path to.
581
#             -w, --wipe
582
#                 Delete .user files as well.
583
# return:
584
#  -  0: no error
459
#             -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.
585 467
#
586
function deleteProjects {
587
  local modulename=""
468
function deleteProject {
469
  local module=""
470
  local modules=()
588 471
  local projectdir=""
589 472
  local outvar=""
590
  local wipe=false
473
  local wipe=""
474
  local modules2delete=()
591 475
  local files=()
476
  local userinput=""
592 477

  
593 478
  # parse arguments
594 479
  local otherargs=()
......
600 485
        -p|--path)
601 486
          projectdir=$(realpath "$2"); shift 2;;
602 487
        -m=*|--module=*)
603
          modulename="${1#*=}"; shift 1;;
488
          module="${1#*=}"; shift 1;;
604 489
        -m|--module)
605
          modulename="${2}"; shift 2;;
490
          module="${2}"; shift 2;;
606 491
        -o=*|--out=*)
607 492
          outvar=${1#*=}; shift 1;;
608 493
        -o|--out)
609 494
          outvar=$2; shift 2;;
495
        -w=*|--wipe=*)
496
          wipe="${1#*=}"; shift 1;;
610 497
        -w|--wipe)
611
          wipe=true; shift 1;;
498
          wipe="$2"; shift 2;;
612 499
        *)
613 500
          printError "invalid option: $1\n"; shift 1;;
614 501
      esac
......
618 505
    fi
619 506
  done
620 507

  
508
  # 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

  
621 515
  # read absolute project directory if required
622 516
  if [ -z "$projectdir" ]; then
623 517
    getProjectDir projectdir
518
    printf "\n"
624 519
  fi
625 520

  
626
  # list all files to be deleted
627
  if [ -z "$modulename" ]; then
628
    if [ $wipe != true ]; then
629
      files=($(find "${projectdir}" -maxdepth 1 -type f | grep -E "^.+\.(includes|files|config|creator|cflags|cxxflags)$"))
630
    else
631
      files=($(find "${projectdir}" -maxdepth 1 -type f | grep -E "^.+\.(includes|files|config|creator|cflags|cxxflags|creator(\.user(\..+)?)?)$"))
521
  # 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
632 555
    fi
556
    printf "\n"
633 557
  else
634
    if [ $wipe != true ]; then
635
      files=($(find "${projectdir}" -maxdepth 1 -type f | grep -E "^${modulename}\.(includes|files|config|creator|cflags|cxxflags)$"))
558
    # 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
636 562
    else
637
      files=($(find "${projectdir}" -maxdepth 1 -type f | grep -E "^${modulename}\.(includes|files|config|creator|cflags|cxxflags|creator(\.user(\..+)?)?)$"))
563
      modules2delete=($module)
638 564
    fi
639 565
  fi
640
  if [ ${#files[@]} != 0 ]; then
641
    printInfo "Deleting the following files:\n"
566

  
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"
642 599
    for file in ${files[@]}; do
643 600
      printInfo "\t$(basename ${file})\n"
644
      rm ${file} 2>&1 | tee -a $LOG_FILE
645 601
    done
602
    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
646 614
  else
647
    printInfo "No project files found\n"
615
    printInfo "No files to delete.\n"
648 616
  fi
649 617

  
618
  # finally delete the files
619
  for file in ${files[@]}; do
620
    rm ${file} 2>&1 | tee -a $LOG_FILE
621
  done
622

  
650 623
  # store the path to the output variable, if required
651 624
  if [ ! -z "$outvar" ]; then
652 625
    eval $outvar="$projectdir"
......
728 701
      case "$1" in
729 702
        -h|--help) # already handled; ignore
730 703
          shift 1;;
731
        -m=*|--module=*)
732
          createModuleProject modules[@] --module="${1#*=}"; printf "\n"; shift 1;;
733
        -m|--module)
734
          createModuleProject modules[@] --module="${2}"; printf "\n"; shift 2;;
735
        -a|--all)
736
          createAllProjects modules[@]; shift 1;;
737
        -c|--clean)
738
          deleteProjects; printf "\n"; shift 1;;
739
        -w|--wipe)
740
          deleteProjects --wipe; printf "\n"; shift 1;;
704
        -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;;
741 712
        -q|--quit)
742 713
          quitScript; shift 1;;
743 714
        --log=*|--LOG=*) # already handled; ignore
......
760 731
    # main menu info prompt and selection
761 732
    printInfo "QtCreator setup main menu\n"
762 733
    printf "Please select one of the following actions:\n"
763
    printf "  [M] - create a project for a single module\n"
764
    printf "  [A] - create a project for all modules\n"
765
    printf "  [C] - clean all project files\n"
766
    printf "  [W] - wipe all project and .user files\n"
734
    printf "  [P] - create project files\n"
735
    printf "  [D] - delete project files\n"
767 736
    printf "  [Q] - quit this setup\n"
768 737
    local userinput=""
769
    readUserInput "MmAaCcWwQq" userinput
738
    readUserInput "PpDdQq" userinput
770 739
    printf "\n"
771 740

  
772 741
    # evaluate user selection
773 742
    case "$userinput" in
774
      M|m)
775
        createModuleProject modules[@]; printf "\n";;
776
      A|a)
777
        createAllProjects modules[@]; printf "\n";;
778
      C|c)
779
        deleteProjects; printf "\n";;
780
      W|w)
781
        deleteProjects --wipe; printf "\n";;
743
      P|p)
744
        createProject modules[@]; printf "\n";;
745
      D|d)
746
        deleteProject; printf "\n";;
782 747
      Q|q)
783 748
        quitScript;;
784 749
      *) # sanity check (exit with error)
......
794 759
################################################################################
795 760

  
796 761
main "$@"
797

  

Also available in: Unified diff