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 13EXPECTED_ANTLR_VERSION_STR="ANTLR Parser Generator Version 3.5" 14 15# Get the location of this script used to find locations of other things in the tree. 16SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 17 18# Point to the directory which contains the ANTLR jars. 19if [[ -z "$ANTLR" ]] 20then 21 # Best effort to find it inside of the gradle cache 22 ANTLR="$(find $HOME/.gradle/caches/artifacts-* -name 'org.antlr' | head -n 1)" 23fi 24 25# Class that contains the static main function. 26ANTLR_MAIN="org.antlr.Tool" 27 28if ! [[ -d "$ANTLR" ]]; then 29 echo >&2 "ERROR: Could not find ANTLR jars directory" 30 exit 1 31fi 32 33# Build up the classpath by finding all the JARs 34ANTLR_JARS="" 35 36for 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" 41done 42 43if [[ -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 47fi 48 49function run_antlr() { 50 CLASSPATH="$ANTLR_JARS" java 2>&1 "$ANTLR_MAIN" "$@" 51} 52 53ANTLR_VERSION="$(run_antlr -version)" 54 55if [[ -z "$ANTLR_VERSION" ]] 56then 57 echo >&2 "ERROR: Failed to execute antlr at \"$ANTLR\"" 58 exit 1 59fi 60 61if [[ "$EXPECTED_ANTLR_VERSION_STR" != "$ANTLR_VERSION" ]] 62then 63 echo >&2 "ERROR: Wrong version of jflex: \"$ANTLR_VERSION\". Expected: \"$EXPECTED_ANTLR_VERSION_STR\"" 64 exit 1 65fi 66 67 68function 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 95function 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 103generate_file "$SCRIPT_DIR/src/main/java/org/jf/smali/smaliParser.java" "$SCRIPT_DIR/src/main/antlr/smaliParser.g" 104generate_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 107cleanup_tokens "$SCRIPT_DIR/src/main/java/org/jf/smali/smaliParser.java" 108cleanup_tokens "$SCRIPT_DIR/src/main/java/org/jf/smali/smaliTreeWalker.java" 109 110# Uncomment to run interactively 111#run_antlr "$@" 112