1#!/bin/bash
2(set -o igncr) 2>/dev/null && set -o igncr; # this comment is required
3set -$-ue${DEBUG+x}
4
5#######################################################################################################################
6# This script is designed to process resource files that are necessary for a single component. It converts each
7# resource file into a binary object and then stores that into an array in a .c file. The .c file can then be compiled
8# with and linked into an application image.
9#
10# Once all resources files have been converted it will generate a header file that references each of them.
11#
12# usage:
13#	genresources.bash <RECIPE_DIR> <SCRIPTS_DIR> <RESOURCE_FILE> <PROJECT_DIR> <TARGET_DIR> <FILESYSTEM|MEM> [s]
14#
15#######################################################################################################################
16
17RECIPE_DIR=$1				#eg: ./tools
18RESOURCE_FILE=$2		    #eg: ./generated/temp.cyrsc
19PROJECT_DIR=$3				#eg: ./project_mainapp
20TARGET_DIR=$4				#eg: ./project_resources
21RESOURCE_TYPE=$5			#eg: FILESYSTEM or MEM
22
23echo Script: genresources.bash
24echo "    1: Recipe Dir     : '"$RECIPE_DIR"'"
25echo "    3: Resource Files : '"$RESOURCE_FILE"'"
26echo "    4: Project Dir    : '"$PROJECT_DIR"'"
27echo "    5: Target Dir     : '"$TARGET_DIR"'"
28echo "    6: Resource Type  : '"$RESOURCE_TYPE"'"
29
30#
31# File in the target directory
32#
33RES_FILE="$TARGET_DIR/cy_resources.h"
34
35# array of c source files parsed for declarations to generate resources.h
36declare SOURCE_ARRAY=()
37
38#
39# Print nice error messages
40#
41function error() {
42    echo "ERROR: $1"
43    shift
44
45    while (( $# > 0 )); do
46        echo "     : $1:"
47        shift
48    done
49
50    echo "—ABORTING--"
51    exit 1
52}
53
54#
55# Checks if the value $1 is in the array $element
56#
57array_contains () {
58    local seeking=$1; shift
59    local in=0
60    for element; do
61        if [[ $element == $seeking ]]; then
62            in=1
63            break
64        fi
65    done
66    echo $in
67}
68
69#
70# Prepares the resource file for outputing as c-file
71#
72convert_resource_name() {
73    local input=$1
74    local result=${input//\//_DIR_} #replace '/' with '_DIR_'
75    result=${result//./_} #replace '.' with '_'
76    result=${result//-/_} #replace '-' with '_'
77    result=${result//resources_DIR/resources} #replace 'resources_DIR' with 'resources'
78    echo $result
79}
80
81#
82# Process the resources listed in the .cyrsc file by converting them to .c and creating
83# a list of files for the resource header script
84#
85processResources() {
86    local TEXT_FILTERS=(html htm txt eml js css dat cer pem json xml py key)
87    local BINARY_FILTERS=(jpg jpeg png ico gif bin flac wav clm_blob gz mp3 wmfw)
88
89    local TEXT_TO_RES="$RECIPE_DIR/text_to_resource_c.pl"
90    local BIN_TO_RES="$RECIPE_DIR/bin_to_resource_c.pl"
91
92    local resourceList=($(<$1))
93
94    # Parse through each element in the .cyrsc file
95    for ((i = 0; i < ${#resourceList[@]}; i++)); do
96
97        # Evaluate the file
98        local resourceFile="${resourceList[$i]}"
99        local filename="${resourceFile##*/}"
100        local extension="${filename##*.}"
101
102        # only process the file if it exists
103        if [ -f "$resourceFile" ]; then
104
105            local resourceName=$(convert_resource_name "$resourceFile")
106            local outputFile="$TARGET_DIR/$(convert_resource_name $filename).c"
107
108            SOURCE_ARRAY+=("$TARGET_DIR/$(convert_resource_name $filename).c")
109
110            local script
111            local isText=$(array_contains $extension "${TEXT_FILTERS[@]}")
112            if [ "1" == "$isText" ]; then
113                script=$TEXT_TO_RES
114            fi
115
116            local isBinary=$(array_contains $extension "${BINARY_FILTERS[@]}")
117            if [ "1" == "$isBinary" ]; then
118                script=$BIN_TO_RES
119            fi
120
121            local outputFileTmp="$TARGET_DIR/$(convert_resource_name $filename).c"
122            perl "$script" "$RESOURCE_TYPE" "$resourceName" "$resourceFile" > "$outputFileTmp"
123        else
124            error  "Listed resource $resourceFile does not exist"
125        fi
126    done
127}
128
129#
130# Remove stale files from previous run
131#
132cleanStale() {
133    local staleList=($(find $TARGET_DIR -name "*.c"))
134    local resourceList=($(<$1))
135    local fileFound=0
136
137    for ((j = 0; j < ${#staleList[@]}; j++)); do
138        for ((i = 0; i < ${#resourceList[@]}; i++)); do
139            local file="${resourceList[$i]}"
140            local filename="${file##*/}"
141            local outputFile="$TARGET_DIR/$(convert_resource_name $filename).c"
142
143            if [[  $(basename $outputFile) ==  $(basename "${staleList[$j]}") ]]; then
144                fileFound=1
145            fi
146        done
147        if [[ $fileFound == 0 ]]; then
148            rm -rf "${staleList[$j]}"
149        fi
150        fileFound=0
151    done
152}
153
154#
155# Call the perl script that creates resources.h
156#
157generateResourceHeader() {
158    perl "$RECIPE_DIR/resources_header.pl" ${SOURCE_ARRAY[*]} > "$RES_FILE"
159}
160
161#######################################################################################################################
162
163#
164# Clean files from previous run that aren't in the current list
165#
166cleanStale $RESOURCE_FILE
167
168#
169# Process all the resources in the cyrsc file
170#
171processResources $RESOURCE_FILE
172
173#
174# Create the resource header
175#
176generateResourceHeader
177
178