1 #!/bin/bash 2 # 3 # This script runs antlr3 generating java code based on .g (ANLTR3) files. 4 # antlr3 tool itself can be downloaded by running the gradle build. 5 # 6 # The script can be run from anywhere (it does not depend on current working directory) 7 # Set $ANTLR to overwrite antlr location, if desired 8 # 9 # After making any changes to the lexer, the update source file(s) generated by 10 # this script should be checked in to the repository 11 12 # Update when switching to a different version of antlr 13 EXPECTED_ANTLR_VERSION_STR="ANTLR Parser Generator Version 3.5.2" 14 15 # Get the location of this script used to find locations of other things in the tree. 16 SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 17 18 # Point to the directory which contains the ANTLR jars. 19 if [[ -z "$ANTLR" ]] 20 then 21 # Best effort to find it inside of the gradle cache 22 ANTLR="$(find $HOME/.gradle/caches/artifacts-* -name 'org.antlr' | head -n 1)" 23 fi 24 25 # Class that contains the static main function. 26 ANTLR_MAIN="org.antlr.Tool" 27 28 if ! [[ -d "$ANTLR" ]]; then 29 echo >&2 "ERROR: Could not find ANTLR jars directory" 30 exit 1 31 fi 32 33 # Build up the classpath by finding all the JARs 34 ANTLR_JARS="" 35 36 for jar_file_name in $(find "$ANTLR" -name '*.jar'); do 37 if ! [[ -z "$ANTLR_JARS" ]]; then 38 ANTLR_JARS+=":" 39 fi 40 ANTLR_JARS+="$jar_file_name" 41 done 42 43 if [[ -z "$ANTLR_JARS" ]]; then 44 echo >&2 "Could not find any JARs in the ANTLR directory" 45 echo >&2 "Is '"$ANTLR"' the correct path to the JARs?" 46 exit 1 47 fi 48 49 function run_antlr() { 50 CLASSPATH="$ANTLR_JARS" java 2>&1 "$ANTLR_MAIN" "$@" 51 } 52 53 ANTLR_VERSION="$(run_antlr -version)" 54 55 if [[ -z "$ANTLR_VERSION" ]] 56 then 57 echo >&2 "ERROR: Failed to execute antlr at \"$ANTLR\"" 58 exit 1 59 fi 60 61 if [[ "$EXPECTED_ANTLR_VERSION_STR" != "$ANTLR_VERSION" ]] 62 then 63 echo >&2 "ERROR: Wrong version of jflex: \"$ANTLR_VERSION\". Expected: \"$EXPECTED_ANTLR_VERSION_STR\"" 64 exit 1 65 fi 66 67 68 function generate_file { 69 local JAVA_FILE="$1" 70 local G_FILE="$2" 71 72 if ! [[ -f "$JAVA_FILE" ]]; then 73 echo >&2 "ERROR: File \"$JAVA_FILE\" not found" 74 exit 1 75 fi 76 77 echo "Re-generating \"$JAVA_FILE\"..." 78 79 [[ -f "$JAVA_FILE" ]] && rm -f "$JAVA_FILE" 80 81 local JAVA_DIR="$(dirname "$JAVA_FILE")" 82 # Generate the java file from the antlr file 83 run_antlr -verbose -fo "$JAVA_DIR" "$G_FILE" 84 85 # delete trailing space from end of each line to make gerrit happy 86 sed 's/[ ]*$//' "$JAVA_FILE" > "$JAVA_FILE.tmp" 87 [[ -f "$JAVA_FILE" ]] && rm "$JAVA_FILE" 88 mv "$JAVA_FILE.tmp" "$JAVA_FILE" 89 90 echo "DONE" 91 echo "" 92 echo "" 93 } 94 95 function cleanup_tokens { 96 local JAVA_FILE="$1" 97 98 # delete the tokens file, they are not necessary to actually build from Android.mk 99 local TOKEN_FILE="${JAVA_FILE%%\.java}.tokens" 100 [[ -f "$TOKEN_FILE" ]] && rm "$TOKEN_FILE" 101 } 102 103 generate_file "$SCRIPT_DIR/src/main/java/org/jf/smali/smaliParser.java" "$SCRIPT_DIR/src/main/antlr/smaliParser.g" 104 generate_file "$SCRIPT_DIR/src/main/java/org/jf/smali/smaliTreeWalker.java" "$SCRIPT_DIR/src/main/antlr/smaliTreeWalker.g" 105 106 # Clean up the tokens, no longer necessary once the tree walker is generated 107 cleanup_tokens "$SCRIPT_DIR/src/main/java/org/jf/smali/smaliParser.java" 108 cleanup_tokens "$SCRIPT_DIR/src/main/java/org/jf/smali/smaliTreeWalker.java" 109 110 # Uncomment to run interactively 111 #run_antlr "$@" 112