[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: