#!/bin/bash
# strip-comment.sh : Supprime les commentaires (/* COMMENT */) d'un progamme C.

E_SANSARGS=0
E_ERREURARG=66
E_MAUVAIS_TYPE_FICHIER=67

if [ $# -eq "$E_SANSARGS" ]
then
  echo "Usage: `basename $0` fichier-C" >&2 # Message d'erreur vers stderr.
  exit $E_ERREURARG
fi  

# Test du type de fichier.
type=`file $1 | awk '{ print $2, $3, $4, $5 }'`
# "file $1" affiche le type du fichier...
# Puis awk supprime le premier champ correspondant au nom du fichier...
# Enfin, le résultat remplit la variable "type".
type_correct="ASCII C program text"

if [ "$type" != "$type_correct" ]
then
  echo
  echo "Ce script fonctionne uniquement sur les fichiers C."
  echo
  exit $E_MAUVAIS_TYPE_FICHIER
fi  


# Script sed assez complexe:
#--------
sed '
/^\/\*/d
/.*\*\//d
' $1
#--------
#  Facile à comprendre si vous prenez quelques heures pour apprendre les
#+ concepts de sed.


#  Il est possible d'ajouter une ligne supplémentaire au script sed pour gérer
#+ le cas où la ligne de code a un commentaire le suivant, sur la même ligne.
#  Ceci est laissé en exercice (difficile).

#  De même, le code ci-dessus supprime les lignes, sans commentaires, avec un
#+ "*/" ou "/*", ce qui n'est pas un effet désirable.

exit 0


# --------------------------------------------------------------------
# Le code ci-dessous ne s'exécutera pas à cause du 'exit 0' ci-dessus.

# Stephane Chazelas suggère l'alternative suivante :

usage() {
  echo "Usage: `basename $0` fichier-C" >&2
  exit 1
}

BIZARRE=`echo -n -e '\377'`   # ou BIZARRE=$'\377'
[[ $# -eq 1 ]] || usage
case `file "$1"` in
  *"C program text"*) sed -e "s%/\*%${BIZARRE}%g;s%\*/%${BIZARRE}%g" "$1" \
     | tr '\377\n' '\n\377' \
     | sed -ne 'p;n' \
     | tr -d '\n' | tr '\377' '\n';;
  *) usage;;
esac

#  Ceci ne fonctionne pas avec, par exemple :
#+ printf("/*");
#+ ou
#+ /*  /* commentaire intégré bogué */
#
#  Pour gérer tous les cas spécifiques (commentaires dans des chaînes,
#+ commentaires dans des chaînes où se trouve un \", \\" ...) la seule façon est
#+ d'écrire un analyseur C (lex ou yacc peut-être ?).

exit 0
