11#! /bin/bash
22
3- # usage: sdcc-link [.lib and .rel files] re5 [other flags and files]
3+ # usage: sdcc-link [options] [.lib and .rel files] re5 [other flags and files]
4+ #
5+ # possible script options (options in this order only):
6+ # -v: verbose
7+ # -d: debug mode (more verbose), includes coloring the output
8+ # -c: color the output
9+
10+
11+ # ## local functions ######################################################
12+
13+ # verbose print
14+ #
15+ # usage: vprint min_level msg
16+ #
17+ # prints a message if the verbosity level is equal or higher than the required
18+ # min_level
19+ #
20+ vprint ()
21+ {
22+ local level=$1
23+
24+ shift
25+ if [ $VERBOSE -ge $level ]; then
26+ echo -e " $@ "
27+ fi
28+ }
29+
30+
31+ # parse the script options
32+ #
33+ # This is very crude. The options are allowed only as the very first argments
34+ # and they are required to be used in exactly this order.
435
536VERBOSE=0
637USE_COLOR=0
738if [ " $1 " == " -v" ]; then
839 VERBOSE=1;
940 shift
10- elif [ " $1 " == " -vv " ]; then
41+ elif [ " $1 " == " -d " ]; then
1142 VERBOSE=2
12- # USE_COLOR=1
43+ USE_COLOR=1
1344 set -x
1445 shift
1546fi
47+ if [ " $1 " == " -c" ]; then
48+ USE_COLOR=1;
49+ shift
50+ fi
51+
1652
53+ # define color codes
1754
1855if [ $USE_COLOR -gt 0 ]; then
1956# ANSI color codes to beautify the output:
@@ -36,59 +73,75 @@ WHITE='\033[1;37m'
3673OFF=' \033[0m'
3774fi
3875
39- # check if cp is in the path using 'command -v' (a builtin POSIX function)
40- if ! command -v cp > /dev/null; then
41- # Ok, this means we are on a Windows system and we have to find a
42- # way to access cp and rm in ../win. A simple 'cd ../win' or
43- # '../win/cp' does't work, as the current working directory is still
44- # the Arduino binary directory.
45- #
46- # This looks ok, but it doesn't work on some Windows systems:
47- # (No idea why)
48- # PATH="${0%/wrapper/*}"/win:$PATH
49- #
50- # This is technically wrong, but surprisingly it works with Windows:
51- # cd $0/../..
52- # PATH=$(pwd)/win:$PATH
53- #
54- # Use cd/pwd as a replacement for 'realpath' using only builtins.
55- # It has the positive side effect of converting from Windows to Unix
56- # path syntax avoiding all these backslash issues.
57- cd " ${0%/ wrapper/* } "
58- PATH=$( pwd) /win:$PATH
59- fi
6076
6177SDCC=" $1 "
6278shift
6379
64- if [ $VERBOSE ]; then
65- # echo the full command line in cyan:
66- >&2 echo -ne " ${CYAN} "
67- >&2 echo -n " ${@ } "
68- >&2 echo -e " ${OFF} "
69- fi
80+ # echo the full command line in cyan on stderr:
81+ >&2 vprint 1 " ${CYAN}${@ }${OFF} "
7082
71- declare -a OBJS
72- while [ $# -gt 0 ]; do
73- echo $1
74- FILE=$1
75- if [[ " $FILE " == * .a ]]; then
76- FILE=${FILE% .a} .lib
77- cp -a " $1 " " $FILE "
78- fi
79- if [[ " $FILE " == * .o ]]; then
80- FILE=${FILE% .o} .rel
83+
84+ # The arduino system insists on a *.a file for a library, but sdar requires
85+ # them to be named *.lib.
86+ #
87+ # Workaround: copy all *.lib files into *.a files.
88+ #
89+ # Iterate over all positional parameters with a for loop.
90+ # The pattern match for filename is easy for bash and dash, but busybox ash
91+ # requires the use of the 'expr' command:
92+ #
93+ # bash, dash: if [[ "$FILE" == *.a ]]; then
94+ # ash uses 'expr': expr "$FILE" : ".*\.a$"; then
95+ #
96+ # This is all pure POSIX, it works for bash, dash and busybox ash
97+ vprint 2 " copy *.a to *.lib"
98+ for FILE; do
99+ vprint 2 " - checking parameter '$FILE '"
100+ # using expr works for bash, dash, busybox ash
101+ if expr " $FILE " : " .*\.a$" > /dev/null; then
102+ NEW=${FILE% .a} .lib
103+ vprint 1 " copy $FILE to $NEW "
104+ cp -a " $FILE " " $NEW "
81105 fi
82- OBJS+=(" ${FILE} " )
83- shift
84106done
85107
86- if [ $VERBOSE ]; then
87- echo -ne " cmd: ${ORANGE} "
88- echo -n " $SDCC " " ${OBJS[@]} "
89- echo -e " ${OFF} "
90- fi
91- " $SDCC " " ${OBJS[@]} "
108+
109+ # replace *.o with *.rel and *.a with *.lib
110+ #
111+ # On bash this is a simple pattern substituiton:
112+ # set -- "${@/.o/.rel}"
113+ # set -- "${@/.a/.lib}"
114+ #
115+ # Unfortunatly, this does not work with dash or ash. dash does not support
116+ # pattern substituition in general. busybox ash does not support arrays and
117+ # shortens the arg list to the first argument, deleting all the rest.
118+ #
119+ # As a workaround we combine the argument list into a single string. By
120+ # using TAB as a field separator we can even deal with spaces, backspaces
121+ # and colons in file names.
122+
123+ # use tab as field separator
124+ IFS=$' \t '
125+
126+
127+ # combine all arguments into a single string with field separator and add a
128+ # TAB at the end. This allows the pattern below to match the last argument
129+ # as well.
130+ vprint 2 " Combine all arguments into a single string"
131+ line=" $* "
132+
133+ # do the filename replacements: (bash and ash, not dash)
134+ # Needs a double slash to replace all occurencies, not only the first one.
135+ # line=${line//.o/.rel}
136+ # line=${line//.a/.lib}
137+ # replace all the occurencies just before a field separator
138+ vprint 2 " - before substitution: $line "
139+ line=" ${line// .o / .rel } "
140+ line=" ${line// .a / .lib } "
141+ vprint 2 " - after substitution: $line "
142+
143+ vprint 1 " cmd: ${ORANGE} $SDCC $line ${OFF} "
144+ " $SDCC " $line
92145
93146# propagate the sdcc exit code
94147exit $?
0 commit comments