Skip to content

Commit

Permalink
Fixes #1:infinite loop on dicts, #16:consumed backtick
Browse files Browse the repository at this point in the history
Added a debug flag for emitting code
  • Loading branch information
kristopolous committed Jan 31, 2012
1 parent 6e3d672 commit 64eda1d
Show file tree
Hide file tree
Showing 9 changed files with 109 additions and 23 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
*~
*swp
.*
15 changes: 15 additions & 0 deletions tests/common.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/bash

error_count=0
test_error() {
(( error_count++ ))
echo "$1"
}

test_done(){
if (( error_count == 0 )); then
echo "Success"
else
echo "Failed " $error_count " tests"
fi
}
9 changes: 0 additions & 9 deletions tests/delete.sh

This file was deleted.

11 changes: 11 additions & 0 deletions tests/delete.test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/bash
. ../ticktick.sh
. ./common.sh

`` key = {"value": 1} ``

[ "``key.value``" == "1" ] || test_error "Key Assignment wrong"
``key.value.delete()``
[ -z "``key.value``" ] || test_error "Key Not Deleted"

test_done
12 changes: 12 additions & 0 deletions tests/dict.test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash
. ../ticktick.sh

# This is reference to issue (1),
# (test case) e.g., parser goes to infinite loop on dicts

# This should parse ok
`` data = { "x" : "y" } ``

# This is a bug in code, but
# it should say so
`` data = { "x" : "y", } ``
8 changes: 8 additions & 0 deletions tests/runall.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash

for i in *.test.sh; do
echo "$i {"
./$i | sed "s/^/ /g"
echo "}"
echo
done
9 changes: 0 additions & 9 deletions tests/runtime.sh

This file was deleted.

12 changes: 12 additions & 0 deletions tests/runtime.test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash
. ../ticktick.sh
. ./common.sh

DATA=`cat data.json`

tickParse "$DATA"

[ "``pathname``" == "/echo/request.json" ] || test_error "Pathname wrong"
[ "``headers["user-agent"]``" == "curl/7.21.6 (i686-pc-linux-gnu) libcurl/7.21.6 OpenSSL/1.0.0e zlib/1.2.3.4 libidn/1.22 librtmp/2.3" ] || test_error "User-agent wrong"

test_done
54 changes: 49 additions & 5 deletions ticktick.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
#!/usr/bin/env bash
ARGV=$@

__tick_error() {
echo "TICKTICK PARSING ERROR: "$1
}

# This is from https://github.com/dominictarr/JSON.sh
# See LICENSE for more info. {{{
__tick_json_tokenize() {
Expand Down Expand Up @@ -50,12 +55,20 @@ __tick_json_parse_object() {
*)
while :
do
# The key, it should be valid
case "$Token" in
'"'*'"'|\$[A-Za-z0-9_]*) key=$Token ;;
# If we get here then we aren't on a valid key
*)
__tick_error "Object without a Key"
break
;;
esac

# A colon
read -r Token

# The value
read -r Token
__tick_json_parse_value "$1" "$key"
obj+="$key:$Value"
Expand Down Expand Up @@ -205,6 +218,18 @@ __tick_fun_parse_expression() {
fi
}

__tick_fun_parse_tickcount_reset() {
# If the tick count is 1 then the backtick we encountered was a
# shell code escape. These ticks need to be preserved for the script.
if (( ticks == 1 )); then
code+='`'
fi

# This resets the backtick counter so that `some shell code` doesn't
# trip up the tokenizer
ticks=0
}

# The purpose of this function is to separate out the Bash code from the
# special "tick tick" code. We do this by hijacking the IFS and reading
# in a single character at a time
Expand Down Expand Up @@ -241,6 +266,8 @@ __tick_fun_parse() {
;;

'')
__tick_fun_parse_tickcount_reset

# this is a newline. If we are in ticktick, then we want to consume
# them for the parser later on. If we are in bash, then we want to
# preserve them. We do this by emitting our buffer and then clearing
Expand All @@ -249,12 +276,11 @@ __tick_fun_parse() {
echo "$code"
unset code
fi

;;

*)
# This resets the backtick counter so that `some shell code` doesn't
# trip up the tokenizer
ticks=0
__tick_fun_parse_tickcount_reset

# This is a buffer of the current code, either bash or backtick
code+="$token"
Expand All @@ -273,8 +299,26 @@ __tick_fun_tokenize() {
# then cat the calling program and push it through our parser
local code=$(cat `caller 1 | cut -d ' ' -f 3` | __tick_fun_parse)

# Take the output and then execute it
bash -c "$code" -- $ARGV
# Before the execution we search to see if we emitted any parsing errors
hasError=`echo "$code" | grep "TICKTICK PARSING ERROR" | wc -l`

if [ $__tick_var_debug ]; then
printf "%s\n" "$code"
exit 0
fi

# If there are no errors, then we go ahead
if (( hasError == 0 )); then
# Take the output and then execute it

bash -c "$code" -- $ARGV
else
echo "Parsing Error Detected, see below"

# printf observes the new lines
printf "%s\n" "$code"
echo "Parsing stopped here."
fi

exit
}
Expand Down

0 comments on commit 64eda1d

Please sign in to comment.