Shellscript für Programmieranfänger

15/08/2008 - 16:16 von Anton Steiner | Report spam
Hallo
Da hier zur Zeit eh nichts los ist, hoffe ich, dass nicht all zu sehr
störe und OT bin :-)
Ich interessiere mich für C, übersetze mir öfter einmal Code-Schnipsel
aus Tutorials und Newsgroups und schreibe auch manchmal auch manchmal
kleine Progràmmchen (nur für mich), für die sich die Erstellung eine
Makefiles nicht auszahlt.
Andererseits geht mir das hàndische Eintippen von "gcc blahfasel..."
auf die Nerven (ich möchte ja möglichst viele Warnungen einschalten
bzw. auf ANSI ode C99 Standard prüfen).
Ich habe deshalb ein Script gebastelt. Es funktioniert, aber
vielleicht könnt ihr es einmal einer anschauen und paar Verbesserungs-
vorschlàge geben.
Am Filecheck auf ".c" und ".h" und anderen Kleinigkeiten bastle ich
gerade.
-
compile.sh

#!/bin/bash

v="0.1a"
arg=""
index=1
infile=""
outfile=""

hstr="usage: compile <mode> file <trailing>
- mode: -s=<std> ansi, c99 (default = none)
-x=<arg> set a argument manually (e.g. \"02\"
-o=<file> outputfile (default inputfile.c = outputfile)
-h show this message and exit
-v version and copyright
- inputfile(s) files only (suffixes .c and .h)
- trail trailing arguments
Example: compile -s=ansi -o=test1file testfile.c -lfoo -lbar"

vstr="$v (c) Anton Steiner, GPL v3.0 or later"


param1="-Wall -Wfloat-equal -Wshadow -Wpointer-arith -Wbad-function-cast \
-Wcast-qual -Wcast-align -Wstrict-prototypes -Wold-style-definition \
-Wmissing-prototypes -Wredundant-decls -Wunreachable-code"

if [ "$#" -eq 0 ]
then
echo -e "$hstr"
exit 1
fi

for arg in "$@"
do
ifp=0
case "${arg:0:2}" in
"-s") case "${arg:3}" in
"ansi") param2="$param1 -pedantic"
ifp=1 ;;
"c99") param2="$param1 -pedantic -std=c99"
ifp=1 ;;
* ) ifp=1 ;;
esac ;;
"-o") outfile="${arg:3}"
ifp=1 ;;
"-x") if [ "$param2" ="" ]
then
param2="$param1 ${arg:3}"
else
param2="$param2 ${arg:3}"
fi
ifp=1 ;;
"-h") echo -e "$hstr"
exit 1 ;;
"-v") echo -e "$vstr"
exit 1 ;;

* ) ;;
esac
if [ "${arg: -2}" = ".c" -o "${arg: -2}" = ".h" ]
then
if [ "$infile" = "" ]
then
of="$arg"
fi
infile="$infile $arg"
ifp=1
fi
if [ "$ifp" -ne 1 ]
then
trail="$trail $arg"
fi
let "index+=1"
done

if [ "$infile" = "" ]
then
echo "no Inputfile"
echo -e "$helpstring"
exit 1;

fi
if [ "$outfile" = "" ]
then
outfile="${of%\.c}"
fi
param3="$param2 -ggdb $infile -o $outfile $trail"

gcc $param3

Vielen Dank und Servus
Anton
in a world without walls and fences - who needs windows and gates ?

IPA-member Linux Registered User # 178376 OE2AZM
oe2azm@oevsv.at oe2azm@yahoo.de
 

Lesen sie die antworten

#1 johannes.tanzler
15/08/2008 - 18:20 | Warnen spam
Anton Steiner wrote:
Ich interessiere mich für C, übersetze mir öfter einmal Code-Schnipsel
aus Tutorials und Newsgroups und schreibe auch manchmal auch manchmal
kleine Progràmmchen (nur für mich), für die sich die Erstellung eine
Makefiles nicht auszahlt.



Ich hab ein Makefile, dass ich einmal zusammengebastelt und jetzt immer
anpasse. Ist praktisch, weil ich die GLib und/oder Gtk+ verwende, die
pkg-config brauchen (aber dafür auch nicht unbedingt den
autoconf-bloat). Vor allem aber kompiliert sich's damit schneller.

# Makefile
CC = gcc
APP = test
CFLAGS = `pkg-config --cflags glib-2.0` -Wall -ansi -pedantic
LDFLAGS = `pkg-config --libs glib-2.0`

SOURCES = file1.c \
file2.c \
main.c
OBJECTS = $(SOURCES:.c=.o)

all: $(APP)

$(APP): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $@

.c.o:
$(CC) -c $(CFLAGS) $< -o $@

clean:
rm -f *.o $(APP)

tags:
ctags *.[ch]

Ich habe deshalb ein Script gebastelt. Es funktioniert, aber
vielleicht könnt ihr es einmal einer anschauen und paar Verbesserungs-
vorschlàge geben.



Fesch, fesch. Dein Skript gefàllt mir. Vor allem erinnert es mich daran,
warum ich keine Shellskripte mehr verwende. Ausdrücke wie
case "${arg:0:2}" in


sind zwar herrlich knackig, aber halt doch etwas schwer zu warten. Aber
ich weiß, dass es Spaß macht, sowas zu schreiben: Ich habe vor ein paar
Jahren "man bash" inhaliert. Doch spàter habe ich aber erkannt, dass
Shell-Skripte des Teufels sind, wenn sie esoterische Features benutzen
und lànger als ein paar Zeilen sind. Trotzdem genier ich mich nicht,
dein Skript zu kommentieren:


- Die Namen param1, param2 und param3 gefallen mir nicht. Ich würde
ihnen entweder aussagekràftige Namen geben, oder nur eine einzige
Variable "param" verwenden. Die kann bei Bedarf verlàngert werden:

PARAM="$PARAM -pedantic"

- Es war einmal Usus, Shell-Variablen nur mit Großbuchstaben zu
schreiben. Das schaut auch so herrlich antik aus.

- Nochwas zum Stil, diesmal Syntax und ebenfalls Geschmackssache:
Ich schreibe

if (foo) {
/* ... */
}

und deshalb auch jedes "then" und "do" in die gleiche Zeile:

if [ "$#" -eq 0 ]; then
# ...
fi

- Da du ohnehin /bin/bash verwendest, kannst du für die Argumente gleich
"getopts" verwenden. Hier eine halbgare getopts-Fassung deiner
Auswertungs-Routine. Ich verwende auch Funktionen und die Macht von
"cat << EOF":


#!/bin/bash
version ()
{
cat << EOF
(C) 2008 MeinName
License: Microsoft Public License
EOF
}

usage ()
{
cat << EOF
usage: $0 [OPTIONS] FILE [FILES ...]

Dieses Skript kompiliert FILE und FILES und rettet die Welt

OPTIONS:
-h Show this message
-s C-Standard. can be 'ansi' or 'C99'.
-x Set arguments manually
-o Outputfile
-v Version and copyright information
EOF
version
}

STANDARDMORE_ARGS
while getopts "hs:r:x:o:v" OPTION ; do
case $OPTION in
h)
usage
exit 0
;;
s)
STANDARD=$OPTARG
;;
x)
MORE_ARGS=$OPTARG
;;
o)
OUTPUTFILE=$OPTARG
;;
v)
version
exit 0
;;
?)
usage
exit
;;
esac
done
shift $(($OPTIND-1)) # $* auf restliche Argumente setzen

if [[ -z $STANDARD ]]; then
STANDARD="ansi"
fi
# usw. für andere Argumente

echo "C-Standard: $STANDARD"
echo "Argumente: $MORE_ARGS"
echo "Outputfile: $OUTPUTFILE"
echo "Dateien: $*"



Johannes

Ähnliche fragen