Re: [un peu HS] argc, argv et exec*()
Marc Chantreux a écrit :
> salut Joël,
Bonjour,
>> 0: sh
>> 1: -c
>> 2: awk 'BEGIN { I=0; } /<comp ref=.*>/ { I=I+1; } { if (I>0) print; }
>> /<\/comp>/ { I=I-1; }' alimentations_haute_tension.xml
>> 3: (null)
>
> du coup, pour ma culture personnelle: quelle raison t'a poussé à choisir
> du C plutôt que de faire un script shell?
Parce que j'ai un traitement assez complexe derrière cette lecture. Le
awk ne me permet que de dégrossir un fichier XML qui fait plus de 1 Mo
en entrée et dont je me moque de la plus grande partie des informations.
> Je n'ai pas posé la question jusqu'a maintenant mais la question me
> brule: tu fais visiblement des forks dans tous les sens et c'est
> typiquement le genre de mécaniques pour lesquelles c'est
> traditionellement le shell qui est utilisé. je me disais que tu te
> passais de cette dépendance avec un programme en C mais si tu dégaines
> sh -c, ca n'est plus une explication.
En fait, l'explication est simple. J'ai besoin d'un bout de code quick
and dirty pour trier certaines informations issues d'un fichier XML
(typiquement, une liste de composants électroniques pour éviter de
perdre du temps au câblage). Ces composants ont besoin d'être triés en
fonction de plusieurs critères (taille, référence, type de composants).
Le tri est en outre particulier, il faut trier sur le caractère
alphabétique et sur le numéro d'ordre.
J'ai brutalement utilisé ceci : http://www.rpl2.fr, en particulier la
commande SYSEVAL qui m'a découpé la ligne en conservant les apostrophes.
C'est dans un second temps que j'ai rajouté l'appel explicite au shell
pour contourner le problème.
#!/home/bertrand/cvs/build/src/rpl -cspd
LISTE_COMPOSANTS
<<
-> FICHIER
<<
"sh -c \"awk 'BEGIN { I=0; } "
"/<comp ref=.*>/ { I=I+1; } " +
"{ if (I>0) print; } " +
"/<\\/comp>/ { I=I-1; }' " +
FICHIER + "\"" +
syseval
{ } 0 ""
-> XML COMPOSANTS L V
<<
XML forall I
I trim
-> FIELD
<<
if
FIELD 1 over size 10 min sub "<comp ref=" same
then
'L' incr
FIELD 11 over size 1 - sub 'V' sto
elseif
FIELD 1 over size 7 min sub "</comp>" same
then
'L' decr
end
if
L 0 >
then
// On ne traite pas les composants imbriqués
if
L 1 same
then
if
FIELD 1 over size 7 min sub
"<value>" same
then
COMPOSANTS
V 2 over size 1 - sub
FIELD dup ">" pos 1 + over size sub
dup "<" pos 1 - 1 swap sub 2 ->table
1 ->list + 'COMPOSANTS' sto
end
end
end
>>
next
COMPOSANTS l->t dup 'COMPOSANTS' sto
<<
-> A B
<<
A { 1 } get B { 1 } get
-> C D
<<
0 1 C size for I
if
C I I sub dup "0" >= swap "9" <= and
then
drop I exit
end
next
C over 1 swap decr sub
swap C swap C size sub 5 "0" rgdl +
0 1 D size for I
if
D I I sub dup "0" >= swap "9" <= and
then
drop I exit
end
next
D over 1 swap decr sub
swap D swap D size sub 5 "0" rgdl +
>>
>>
<
>>
sort 'COMPOSANTS' sto
0 0
-> SMAX1 SMAX2
<<
COMPOSANTS forall I
if
I { 1 } get size dup SMAX1 >
then
'SMAX1' sto
else
drop
end
if
I { 2 } get size dup SMAX2 >
then
5 + 'SMAX2' sto
else
drop
end
next
"NAME" FICHIER ".bom" + 2 ->list 1 ->list
{ "UNKNOWN" "FLOW" } + open
{ "LINE*(*)" } swap format
-> F
<<
COMPOSANTS forall I
I { 1 } get SMAX1 " " rgdl
I { 2 } get SMAX2 " " rgdl +
1 ->list F write
next
F close
>>
>>
>>
>>
clmf
>>
128 lignes our un code absolument pas optimisé, mais le truc a été codé
et débuggué en une demi-heure et génère exactement ce qu'il me faut :
hilbert:[~/cvs/electronique/alimentations_haute_tension_200W_412V] >
time ./liste_composants.rpl -A \"alimentations_haute_tension.xml\"
+++RPL/2 (R) version 4.1.32 (Dimanche 01/11/2020, 23:15:59 CET)
+++Copyright (C) 1989 à 2019, 2020 BERTRAND Joël
real 0m0,190s
user 0m0,110s
sys 0m0,008s
hilbert:[~/cvs/electronique/alimentations_haute_tension_200W_412V] >
cat alimentations_haute_tension.xml.bom
C1 10nF/100V
C2 10nF/100V
C3 10nF/100V
C4 10nF/100V
C5 22pF/50V
C6 22nF/50V
C7 22nF/50V
C8 22pF/50V
C9 22nF/50V
C10 2.2nF/50V
...
R60 27k_0.25W
R61 330k_0.25W
R62 10k_0.25W
R63 56k_0.25W
R64 2k2_0.25W
...
ce qui est pour moi du temps gagné indéniable, les BOM classiques
regroupant les composants par valeur (lorsque tu as 300 résistances, il
est pénible de devoir rechercher la valeur au milieu des 300
résistances). Même chose pour le tri par taille. On met les gros
composants à la fin parce qu'on les soude en dernier.
Bien cordialement,
JKB
Reply to: