<commit_before>#!/bin/bash

#########
# Regex #
#########

# This is a perl style regex. Sorry
declare -r urlRegex='\b((?:https?:(?:/{1,3}|[a-z0-9%]))(?:[^\s()<>{}[]]+|([^\s()]?([^\s()]+)[^\s()]?)|([^\s]+?))+(?:([^\s()]?([^\s()]+)[^\s()]?)|([^\s]+?)|[^\s`!()[]\{\};:'"'"'".,<>?«»“”‘’]))'

###########
# general #
###########

# kill the specified process and all of its children
#
# The leaf processes are killed first, then it works up to the input
#
# @. a list of pid numbers. quoting does not matter
killtree() {
  local -a safePids=()
  for arg in "$@"; do
    if (( $arg > 0 )); then
      safePids+=( "$arg" )
    fi
  done
  if (( ${#safePids[@]} > 0 )); then
    local joinedPids=$(sed -E 's/\s+/,/g' <<< "${safePids[@]}")

    local -ra children=( $(pgrep -P "$joinedPids") )
    if [[ ${#children[@]} != 0 ]]; then
      killtree ${children[@]}
    fi
    kill -TERM ${safePids[@]}
  fi
}

# If stdin is empty print an error message
#
# 1.message the message to print
ifEmpty() {
  local -r message="$1"

  if read -r line; then
    cat <( echo "$line" ) -
  else
    echo "$message"
  fi
}

# get the message after the initial mention
#
# 1.inputString the whole irc command as one string
# 2.nick optional nick to parse
#
# stdout. the string message text
getMessageNoNick() {
  local -r inputString="$1"
  local -r nick="$2"

  local nickPattern
  if [[ -n "$nick" ]]; then
    nickPattern="$nick\W?\s*"
  fi

  sed -E "s/^(\S+\s+){3}:(.*)/\2/I;s/^$nickPattern//" <<< "$inputString"
}

# Checks if the type of a variable matches the specified type
checkType() {
  local -r variable="$1"
  local -r type="$2"

  declare -p "$variable" 2>/dev/null | grep -qE "^declare -$type"
  return $?
}

# resplit the passed parameters taking into account quoting
#
# @. parameters to split
resplitAndParse() {
  local -a splitArgs=()
  while IFS= read -r -d $'\0' arg; do
    splitArgs[i++]="$arg"
  done < <(printf "%s " "$@" | sed 's/ $//' | resplit.awk)
  parseArgs "${splitArgs[@]}"
}

declare -A argMap=()
declare -a vargs=()

# Parses the input arguments into a hashmap
#
# Any found parameters are placed into the argMap associative array
# The remaining arguments are placed into the vargs array
#
# @. the arguments to parse
parseArgs() {
  local arg
  local getNext=false
  local previous
  local i
  local -A parameterSet=()
  shopt -s extglob

  if checkType assignableParameters a; then
    for parameter in "${assignableParameters[@]}"; do
      parameterSet["$parameter"]=
    done
  fi

  local -r shortOption="-+([a-zA-Z])"
  local -r longOption="--+([a-zA-Z])"

  if checkType argMap A && checkType vargs a; then

    argMap=()
    vargs=()

    while (( $# > 0 )); do
      arg="$1"
      shift
      
      case "$arg" in
        $shortOption )
          if "$getNext"; then
            argMap["$previous"]=
          fi

          if (( ${#arg} == 2 )); then
            local char="${arg:1:1}"
            if [[ -n "${!parameterSet[@]}" ]] && [[ "${parameterSet[$char]+_}" ]]; then
              previous="$char"
              getNext=true
            else
              argMap["$char"]=
              previous=
              getNext=false
            fi
          else
            previous=
            getNext=false
            # the following code is safe due to the invariant that i is [a-zA-Z]{1}
            for i in $(grep -o . <<< "${arg#-}"); do
              # add empty key
              argMap[$i]=
            done
          fi
          ;;
        -- ) 
          if "$getNext"; then
            argMap["$previous"]=
            previous=
            getNext=false
          fi
          vargs+=( "$@" )
          break<commit_msg>fixing multiarg parsing when last is parameter<commit_after>#!/bin/bash

#########
# Regex #
#########

# This is a perl style regex. Sorry
declare -r urlRegex='\b((?:https?:(?:/{1,3}|[a-z0-9%]))(?:[^\s()<>{}[]]+|([^\s()]?([^\s()]+)[^\s()]?)|([^\s]+?))+(?:([^\s()]?([^\s()]+)[^\s()]?)|([^\s]+?)|[^\s`!()[]\{\};:'"'"'".,<>?«»“”‘’]))'

###########
# general #
###########

# kill the specified process and all of its children
#
# The leaf processes are killed first, then it works up to the input
#
# @. a list of pid numbers. quoting does not matter
killtree() {
  local -a safePids=()
  for arg in "$@"; do
    if (( $arg > 0 )); then
      safePids+=( "$arg" )
    fi
  done
  if (( ${#safePids[@]} > 0 )); then
    local joinedPids=$(sed -E 's/\s+/,/g' <<< "${safePids[@]}")

    local -ra children=( $(pgrep -P "$joinedPids") )
    if [[ ${#children[@]} != 0 ]]; then
      killtree ${children[@]}
    fi
    kill -TERM ${safePids[@]}
  fi
}

# If stdin is empty print an error message
#
# 1.message the message to print
ifEmpty() {
  local -r message="$1"

  if read -r line; then
    cat <( echo "$line" ) -
  else
    echo "$message"
  fi
}

# get the message after the initial mention
#
# 1.inputString the whole irc command as one string
# 2.nick optional nick to parse
#
# stdout. the string message text
getMessageNoNick() {
  local -r inputString="$1"
  local -r nick="$2"

  local nickPattern
  if [[ -n "$nick" ]]; then
    nickPattern="$nick\W?\s*"
  fi

  sed -E "s/^(\S+\s+){3}:(.*)/\2/I;s/^$nickPattern//" <<< "$inputString"
}

# Checks if the type of a variable matches the specified type
checkType() {
  local -r variable="$1"
  local -r type="$2"

  declare -p "$variable" 2>/dev/null | grep -qE "^declare -$type"
  return $?
}

# resplit the passed parameters taking into account quoting
#
# @. parameters to split
resplitAndParse() {
  local -a splitArgs=()
  while IFS= read -r -d $'\0' arg; do
    splitArgs[i++]="$arg"
  done < <(printf "%s " "$@" | sed 's/ $//' | resplit.awk)
  parseArgs "${splitArgs[@]}"
}

declare -A argMap=()
declare -a vargs=()

# Parses the input arguments into a hashmap
#
# Any found parameters are placed into the argMap associative array
# The remaining arguments are placed into the vargs array
#
# @. the arguments to parse
parseArgs() {
  local arg
  local getNext=false
  local previous
  local i
  local -A parameterSet=()
  shopt -s extglob

  if checkType assignableParameters a; then
    for parameter in "${assignableParameters[@]}"; do
      parameterSet["$parameter"]=
    done
  fi

  local -r shortOption="-+([a-zA-Z])"
  local -r longOption="--+([a-zA-Z])"

  if checkType argMap A && checkType vargs a; then

    argMap=()
    vargs=()

    while (( $# > 0 )); do
      arg="$1"
      shift
      
      case "$arg" in
        $shortOption )
          if "$getNext"; then
            argMap["$previous"]=
          fi

          if (( ${#arg} == 2 )); then
            local char="${arg:1:1}"
            if [[ -n "${!parameterSet[@]}" ]] && [[ "${parameterSet[$char]+_}" ]]; then
              previous="$char"
              getNext=true
            else
              argMap["$char"]=
              previous=
              getNext=false
            fi
          else
            previous=
            getNext=false
            # the following code is safe due to the invariant that i is [a-zA-Z]{1}
            for i in $(grep -o . <<< "${arg#-}"); do
              if [[ -n "$previous" ]]; then
                argMap["$previous"]=
              fi
              if [[ -n "${!parameterSet[@]}" ]] && [[ "${parameterSet[$i]+_}" ]]; then
                previous="$i"
                getNext=true
              else
                argMap["$i"]=
                previous=
                getNext=false
              fi
            done
          fi
          ;;
        -- ) 
          if "$getNext"; then
            argMap["$previous"]=
            previous=
            getNext=false
          fi
          vargs+=( "$@" )
          break
{'fraction_non_alphanumeric': 0.1946868081781482, 'fraction_numerical': 0.0065112644875634845, 'mean_word_length': 2.1801242236024843, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3045686', 'n_tokens_mistral': 2618, 'n_tokens_neox': 2542, 'n_words': 759}