130 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			130 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
| # The MIT License
 | |
| #
 | |
| # Copyright (c) 2011 Dominic Tarr
 | |
| #
 | |
| # Permission is hereby granted, free of charge,
 | |
| # to any person obtaining a copy of this software and
 | |
| # associated documentation files (the "Software"), to
 | |
| # deal in the Software without restriction, including
 | |
| # without limitation the rights to use, copy, modify,
 | |
| # merge, publish, distribute, sublicense, and/or sell
 | |
| # copies of the Software, and to permit persons to whom
 | |
| # the Software is furnished to do so,
 | |
| # subject to the following conditions:
 | |
| #
 | |
| # The above copyright notice and this permission notice
 | |
| # shall be included in all copies or substantial portions of the Software.
 | |
| #
 | |
| # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | |
| # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 | |
| # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 | |
| # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
 | |
| # ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 | |
| # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 | |
| # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | |
| #
 | |
| #
 | |
| # https://github.com/dominictarr/JSON.sh
 | |
| #
 | |
| throw () {
 | |
|   echo "$*" >&2
 | |
|   exit 1
 | |
| }
 | |
| 
 | |
| tokenize () {
 | |
|   local ESCAPE='(\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})'
 | |
|   local CHAR='[^[:cntrl:]"\\]'
 | |
|   local STRING="\"$CHAR*($ESCAPE$CHAR*)*\""
 | |
|   local NUMBER='-?(0|[1-9][0-9]*)([.][0-9]*)?([eE][+-]?[0-9]*)?'
 | |
|   local KEYWORD='null|false|true'
 | |
|   local SPACE='[[:space:]]+'
 | |
|   egrep -ao "$STRING|$NUMBER|$KEYWORD|$SPACE|." --color=never |
 | |
|     egrep -v "^$SPACE$"  # eat whitespace
 | |
| }
 | |
| 
 | |
| parse_array () {
 | |
|   local index=0
 | |
|   local ary=''
 | |
|   read -r token
 | |
|   case "$token" in
 | |
|     ']') ;;
 | |
|     *)
 | |
|       while :
 | |
|       do
 | |
|         parse_value "$1" "$index"
 | |
|         let index=$index+1
 | |
|         ary="$ary""$value" 
 | |
|         read -r token
 | |
|         case "$token" in
 | |
|           ']') break ;;
 | |
|           ',') ary="$ary," ;;
 | |
|           *) throw "EXPECTED , or ] GOT ${token:-EOF}" ;;
 | |
|         esac
 | |
|         read -r token
 | |
|       done
 | |
|       ;;
 | |
|   esac
 | |
|   value=`printf '[%s]' "$ary"`
 | |
| }
 | |
| 
 | |
| parse_object () {
 | |
|   local key
 | |
|   local obj=''
 | |
|   read -r token
 | |
|   case "$token" in
 | |
|     '}') ;;
 | |
|     *)
 | |
|       while :
 | |
|       do
 | |
|         case "$token" in
 | |
|           '"'*'"') key=$token ;;
 | |
|           *) throw "EXPECTED string GOT ${token:-EOF}" ;;
 | |
|         esac
 | |
|         read -r token
 | |
|         case "$token" in
 | |
|           ':') ;;
 | |
|           *) throw "EXPECTED : GOT ${token:-EOF}" ;;
 | |
|         esac
 | |
|         read -r token
 | |
|         parse_value "$1" "$key"
 | |
|         obj="$obj$key:$value"        
 | |
|         read -r token
 | |
|         case "$token" in
 | |
|           '}') break ;;
 | |
|           ',') obj="$obj," ;;
 | |
|           *) throw "EXPECTED , or } GOT ${token:-EOF}" ;;
 | |
|         esac
 | |
|         read -r token
 | |
|       done
 | |
|     ;;
 | |
|   esac
 | |
|   value=`printf '{%s}' "$obj"`
 | |
| }
 | |
| 
 | |
| parse_value () {
 | |
|   local jpath="${1:+$1,}$2"
 | |
|   case "$token" in
 | |
|     '{') parse_object "$jpath" ;;
 | |
|     '[') parse_array  "$jpath" ;;
 | |
|     # At this point, the only valid single-character tokens are digits.
 | |
|     ''|[^0-9]) throw "EXPECTED value GOT ${token:-EOF}" ;;
 | |
|     *) value=$token ;;
 | |
|   esac
 | |
|   printf "[%s]\t%s\n" "$jpath" "$value"
 | |
| }
 | |
| 
 | |
| parse () {
 | |
|   read -r token
 | |
|   parse_value
 | |
|   read -r token
 | |
|   case "$token" in
 | |
|     '') ;;
 | |
|     *) throw "EXPECTED EOF GOT $token" ;;
 | |
|   esac
 | |
| }
 | |
| 
 | |
| if [ $0 = $BASH_SOURCE ];
 | |
| then
 | |
|   tokenize | parse
 | |
| fi
 |