OVH Cloud OVH Cloud

Script avec sed et ses amis...

12 réponses
Avatar
JKB
Bonjour à tous,

Je viens de m'apercevoir d'une mise à jour de cpp sur certains de
mes système (qui met la pagaille dans un soft que j'ai écrit il y a
quelques années...).

En gros, j'ai des scripts qui utilisent les directives du
préprocesseur (#include, #if/#else/#endif et c'est à peu près tout)
_et_ les commentaires façon C++, à savoir // et /*....*/. J'ai aussi
mes propres objets qui peuvent commencer par # (mais pas en première
colonne). Aujourd'hui, le cpp livré avec gcc récupère les objets
commençant par # en début de ligne (mais pas en première colonne)
comme des directives s'adressant à lui. Comme il ne les reconnaît
pas, il les vire du script et la suite se passe mal...

J'essaye donc d'écrire un script tout bête recherchant les
caractères # précédés d'au moins un espace ou une tabulation et de
rien d'autre (je sais faire avec sed) et de concaténer cette ligne
avec la ligne précédente (je ne sais plus faire, pourtant j'ai
rtfmer sed). Une idée (avec sed ou awk) ? Cela doit rentrer dans le
script suivant :

#/bin/bash

CPP=$(which cpp 2>&1 | cut -d ':' -f1)

if [ $CPP = "which" -o -z $CPP ]; then
i=0
chaine=`gcc -v 2>&1 | awk '/^Reading specs from/ {printf("%s\n", $4);}'`

for j in `echo $chaine | tr '/' ' '`;
do
i=$(($i+1))
done;

commande=`echo $chaine | cut -d '/' -f -$i`/cpp
else
commande=cpp
fi

sed -e '1,1s/^#!/\/\//g' $1 | \
$commande -P -I. -nostdinc 1> $2 2> /dev/null

exit 0

J'ai essayé une autre solution : appeler cpp avec --traditional-cpp,
mais je n'ai plus les commentaires façon C++ (//). Une autre piste
serait de repérer tous les // en dehors des chaînes de caractères
pour les remplacer par des /*...*/, mais ça me semble beaucoup plus
compliquer (il faut avoir un drapeau pour savoir si on est ou non
dans une chaîne de caractères...).

Merci de votre attention,

JKB

2 réponses

1 2
Avatar
JKB
Le 20-12-2004, à propos de
Re: Script avec sed et ses amis...,
Stephane Chazelas écrivait dans fr.comp.os.unix :
2004-12-20, 18:21(+01), cedric:
[...]
Pour ca, on trouve sur google un 'truc'
accablant de malice :

sed ':a;N;$!ba;s/n[ t]#//g'
[...]


Pas POSIX. Les intructions qui prennent des labels et w et r et
} ne doivent pas avoir des trucs qui les suivent. t n'est pas
garantit d'etre reconnu.

sed -e :a -e 'N;$!ba' -e 's/n([[:blank:]]#)/1/g'

POSIX ne garantit pas que ca marchera pour des fichiers gros de
plus de 8192 octets. La solution awk que je donnais n'a de
limitation que sur la longueur des lignes (POSIX garantit 2048).

perl -0777 -pe 's/n(s#)/$1/g'

devrait marcher sans limitations.


Merci pour vos contributions. Entre temps, j'ai trouvé gpp qui fait
exactement ce qu'il faut. Mais je note toutes vos remarques.

Cordialement,

JKB


Avatar
John Mackerel
JKB wrote:

Merci pour vos contributions. Entre temps, j'ai trouvé gpp qui fait


GOTO++ ? j'ai du mal à y croire !

1 2