bash로 Stack 구조 구현

######################################################################
# Stack 함수: Stack을 생성한다.
# Example: func_stack_new name
######################################################################
func_stack_new() {
  : ${1?'Missing stack name'}
  if func_stack_exists $1
  then
    echo "Stack already exists -- $1" >&2
    return 1
  fi

  eval "declare -ag _stack_$1"
  eval "declare -ig _stack_$1_i"
  eval "let _stack_$1_i=0"
  return 0
}

######################################################################
# Stack 함수: Stack을 제거한다.
# Example: func_stack_destroy name
######################################################################
func_stack_destroy() {
  : ${1?'Missing stack name'}
  eval "unset _stack_$1 _stack_$1_i"
  return 0
}

######################################################################
# Stack 함수: Push
# Example: func_stack_push stack item ...
######################################################################
func_stack_push() {
  : ${1?'Missing stack name'}
  : ${2?'Missing item(s) to push'}

  if func_no_such_stack $1
  then
    echo "No such stack -- $1" >&2
    return 1
  fi

  stack=$1
  shift 1

  while (( $# > 0 ))
  do
    eval '_i=$'"_stack_${stack}_i"
    eval "_stack_${stack}[$_i]='$1'"
    eval "let _stack_${stack}_i+=1"
    shift 1
  done

  unset _i
  return 0
}

######################################################################
# Stack 함수: Pop
# Example: func_stack_pop mystack top
#          echo "Got $top"
######################################################################
func_stack_pop() {
  : ${1?'Missing stack name'}
  : ${2?'Missing name of variable for popped result'}

  eval 'let _i=$'"_stack_$1_i"
  if func_no_such_stack $1
  then
    echo "No such stack -- $1" >&2
    return 1
  fi

  if [[ "$_i" -eq 0 ]]
  then
    echo "Empty stack -- $1" >&2
    return 1
  fi

  let _i-=1
  eval "$2"='$'"{_stack_$1[$_i]}"
  eval "unset _stack_$1[$_i]"
  eval "_stack_$1_i=$_i"
  unset _i
  return 0
}

######################################################################
# Stack 함수: Stack 전체를 출력한다.
# Example: func_stack_print name
######################################################################
func_stack_print() {
  : ${1?'Missing stack name'}

  if func_no_such_stack $1
  then
    echo "No such stack -- $1" >&2
    return 1
  fi

  tmp=""
  eval 'let _i=$'_stack_$1_i
  while (( $_i > 0 ))
  do
    let _i=${_i}-1
    eval 'e=$'"{_stack_$1[$_i]}"
    tmp="$tmp $e"
  done
  echo "(" $tmp ")"
}

######################################################################
# Stack 함수: Stack 크기를 알아낸다.
# Example: func_stack_size mystack n
#          echo "Size is $n"
######################################################################
func_stack_size() {
  : ${1?'Missing stack name'}
  : ${2?'Missing name of variable for stack size result'}
  if func_no_such_stack $1
  then
    echo "No such stack -- $1" >&2
    return 1
  fi
  eval "$2"='$'"{#_stack_$1[*]}"
}

func_stack_exists() {
  : ${1?'Missing stack name'}

  eval '_i=$'"_stack_$1_i"
  if [[ -z "$_i" ]]
  then
    return 1
  else
    return 0
  fi
}

func_no_such_stack() {
  : ${1?'Missing stack name'}
  func_stack_exists $1
  ret=$?
  declare -i x
  let x="1-$ret"
  return $x
}
위로 스크롤