1

Je suis en train d'écrire un archiveur en ligne de commande pour PedroM.

J'aimerais vos idées pour le design, même si je pense avoir fait la majeure partie du boulot maintenant :
Par



Syntax        par [options] [archive à traiter] [liste de fichiers]



Options

-a,--add
        Ajoute les fichiers à l'archive. Crée l'archive si elle n'existe pas.
        Si l'archive existe en flash, elle est désarchivée et réarchivée à la fin.
        Défaut:
        - N'enregistre pas le chemin absolu des fichiers.
        - Si un fichier du même nom existe dans l'archive, renvoie une erreur.


-e,--extract
        Désarchive les fichiers spécifiés dans la liste.
        Défaut:
        - Utilise le chemin absolu des fichiers s'il existe dans l'archive, sinon extrait dans le répertoire courant.
        - Désarchive les fichiers spécifiés dans la liste, sinon désarchive tous les fichiers.
        - Si un fichier à désarchiver existe déjà, renvoie une erreur.


-r,--remove
        Détruit les fichiers dans une archive. Désarchive l'archive si elle est en flash et l'y remet à la fin.


-l,--list
        Affiche des informations sur une archive et sur les fichiers contenus.
        Défaut: affiche les informations de tous les fichiers (nom, taille, type), sauf si une liste est spécifiée.


-f,--flash
        Si on crée une archive, elle est mise en flash à la fin de l'opération.
        Si on extrait des fichiers, ils sont mis en flash au fur et à mesure.


-s,--save-path
        Enregistre le chemin absolu des fichiers ajoutés à une archive. Si aucun path n'est spécifié pour un fichier,
        le répertoire courant est enregistré.


-d,--dir <fld>
        Extrait les fichiers listés/tous les fichiers dans le répertoire fld, sans tenir compte de l'éventuel chemin
        enregistré. '.' signifie 'répertoire courant'.
        Défaut:
        - renvoie une erreur si le répertoire n'existe pas.


-F,--force
        Ecrase les fichiers dans une archive quand on veut y ajouter un fichier déjà présent.
        Ecrase les fichiers existants quand on désarchive des fichiers.
        Crée automatiquement le répertoire fld de l'option -d si le répertoire n'existe pas.


-c,--continue
        En cas d'erreur non fatale (fichier existant et pas d'option -f spécifiée, fichier inexistant,
        nom invalide etc...), ignore le fichier et passe au suivant.
        

-v,--verbose
        Mode verbeux sur stdout.
        Défaut:
        - Par ne renvoie que les erreurs sur stderr.


-h,--help
        Affiche une aide sur les différentes options.


Notes
        - Les archives sont créées en RAM.
        - Les fichiers sont extraits en RAM.
        - Les fichiers sont ajoutés dans une archive sans information de path.
        - Les fichiers sont extraits en utilisant l'information de path si elle existe, sinon dans le répertoire courant.
        - Si --add/--extract/--remove/--list sont spécifiés, le dernier switch passé est utilisé, les autres ignorés.
        - Si des options incohérentes sont spécifiées (par exemple, --force quand on liste une archive), elles sont ignorées silencieusement.

Voilà, toutes vos idées et critiques sont les bienvenues.

Merci déjà à Zerosquare pour les siennes et la lecture de mon code (le programme est déjà capable de créer une archive, d'y mettre des fichiers, tout ce qui est chemin absolu ou non est géré, ainsi que les archivages/désarchivages nécessaires).

ps -> Je voudrais que Par signifie "PedroM Archiver". J'avais déjà fait ça pour Pexec, avant de me poser une question : quid d'utiliser un nom de programme dont je ne possède pas le copyright dans le mien ? PpHd saura sûrement me répondre. cheeky C'est en fait pour ça que j'avais renommé Pexec en EExec, même si PpHd n'avait rien dit... bref je ne veux pas faire de pas de travers niveau droit/license/toussa.

ps2 -> Par utilise une petite lib perso, Pdtlib (~15 fonctions pour le moment), qui m'aide énormément à gérer de tels softs : trouver/créer/archiver/déasrchiver les fichiers, lire le fichier de configuration du soft au boot (system\par), mais aussi gérer la ligne de commande. L'API de la fonction qui le fait n'a pas changé depuis ce que j'ai écrit sur mon blog, pourtant elle gère maintenant les options longues et courtes de manière tout aussi simplissime pour le programmeur, merci à Zerosquare pour cette idée-là aussi. happy


Voilà, j'attends vos critiques. smile

2

Bah, si tu dis que Par signifie Powerful ARchiver ou quelque chose du genre, tu ne risques aucun ennui. smile

(Vive The Incredible Graphing Calculator Compiler! tongue)
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

3

m'étonnerait que ça dérange Pedrom PhD (trilove), ça embarrassed

4

Sympa comme projet top

Question bête : peut-il être utilisé comme lib kernel ?
avatar
<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appétissant

5

Ah ben tu poses une très bonne question au contraire, je voulais en parler mais j'ai oublié. Là j'ai du taf à faire dans la maison, mais j'ai un début d'API pour que le programme puisse être utilisé comme backend d'un GUI, c'est prévu. Mais si c'est très faisable sur le plan technique, je n'ai pas résolu encore tous les problèmes de concept liés à sa mise en place. J'y reviendrai plus tard, mais aujourd'hui. smile


Pour les droits, je pense avec besoin d'une autorisation explicite, c'est la moindre des choses, non ? Imaginons que PpHd veuille faire un archiveur comprenant le nom "PedroM", je n'ai certainement pas le droit de préempter ce nom alors que c'est le sien, c'est évident...

6

si tu penses trop à tes APIs pendant que tu bricoles, tu vas finir comme Kochise qui écoute Pérusse sad

pour les droits:
!call pphd
--- Call : pphd appelé(e) sur ce topic ...

7

(grin)

8

Folco (./1) :
ps -> Je voudrais que Par signifie "PedroM Archiver". J'avais déjà fait ça pour Pexec, avant de me poser une question : quid d'utiliser un nom de programme dont je ne possède pas le copyright dans le mien ? PpHd saura sûrement me répondre. mod.gif C'est en fait pour ça que j'avais renommé Pexec en EExec, même si PpHd n'avait rien dit... bref je ne veux pas faire de pas de travers niveau droit/license/toussa.


Pas de problèmes voyons !
Faut que j'envoie le papier signé à quelle adresse ?

9

Merci beaucoup grin C'est juste que c'est normal que je demande. Et t'as pas forcément envie de voir le premier soft en script qui additionne deux entiers s'affubler de "PedroM Advanced Mathematics Ingeneering Tool Suite". grin
Puis comme disait un célèbre auteur contemporain : topics/32855-romcall-mem/3#84 tongue

A propos PpHd, des critiques ? cheeky

10

Folco (./9) :
Merci beaucoup biggrin.gif C'est juste que c'est normal que je demande. Et t'as pas forcément envie de voir le premier soft en script qui additionne deux entiers s'affubler de "PedroM Advanced Mathematics Ingeneering Tool Suite". biggrin.gif

Allons, allons, ca me ferra quand même plaisir :==happy
Folco (./9) :
Puis comme disait un célèbre auteur contemporain : topics/32855-romcall-mem/3#84 tongue.gif

C'est pas vrai ! Faut vraiment que je fasse gaffe de ne pas dire n'importe quoi avec toi !
Folco (./9) :
A propos PpHd, des critiques ? mod.gif

Oué, les options longues servent à rien (trop long pour ti), et même pour les options courtes j’enlèverai le '-' pour que ca soit plus court à taper.

11

PpHd (./10) :
Oué, les options longues servent à rien (trop long pour ti)

Ca a de la gueule, ça fait plus mieux vrai trilove
Mais ok.
PpHd (./10) :
et même pour les options courtes jâ&#x20AC;™enlèverai le '-' pour que ca soit plus court à taper.

Et tu fais comment pour différencier un fichier d'une option ?
Ou alors -xlkjsdfjherterqmsdflkjg façon tar ? C'est juste imbitable, mais bon grin

L'avantage de l'état actuel des choses est que ça gère aussi les options du genre --truc <argument de truc> --machin.
Le code est court pour gérer tout ça (et 700 octets pour l'ensemble de la lib, qui est rentabilisée par un seulement deux programmes de ce type, et exécutable en archive).
ManageCommandLine
;==============================================================================
;       Registers usage:
;       a2      callback
;       a3      switchlist (current)
;       d3      #opt / misc
;
;       Offset of args in the stack :
FRAME_BASE      equ     4+4*4            ; 4 registers saved + return address
CMDLINE         equ     0+FRAME_BASE
DATA_PTR        equ     4+FRAME_BASE
SWITCHLIST      equ     8+FRAME_BASE
CALLBACK        equ     12+FRAME_BASE
SWITCHFUNC      equ     16+FRAME_BASE
;==============================================================================

pdtlib@0002:
    ;-----------------------------------------------
    ;    Check if an arg remains
    ;-----------------------------------------------
        movem.l d3-d4/a2-a3,-(sp)
        movea.l CALLBACK(sp),a2                         ; Callback : a2
\Loop:    movea.l CMDLINE(sp),a0                          ; CMDLINE*
        bsr.s   pdtlib@000A                             ; Get next arg
        move.l  a0,d0
        bne.s   \StillArgs
                moveq.l #PDTLIB_END_OF_PARSING,d0       ; No more arg, quit
\Quit:          movem.l (sp)+,d3-d4/a2-a3
                rts

    ;-----------------------------------------------
    ;    Check if it is a long or a short switch
    ;-----------------------------------------------
\StillArgs:
    movea.l    SWITCHLIST(sp),a3
    moveq.l    #-4,d3
    cmpi.b    #'-',(a0)
    bne.s    \NoMinus
        cmpi.b    #'-',1(a0)
        beq.s    \LongSwitch
        bra.s    \ShortSwitch
\NoMinus:
    cmpi.b    #'+',(a0)
    beq.s    \Plus
        ;-----------------------------------------------
        ;    Not a switch, inform the program
        ;-----------------------------------------------
        moveq.l #PDTLIB_NOT_A_SWITCH,d0
                movea.l DATA_PTR(sp),a0
                jsr     (a2)
                moveq.l #PDTLIB_NOT_A_SWITCH,d1
\TestCallbackReturn:
                subq.w  #PDTLIB_STOP,d0                 ; Continue or stop, depending on
                bne.s   \Loop                           ; callback result
                        move.w  d1,d0
                        bra.s   \Quit
\Plus:    cmpi.b    #'+',1(a0)
    beq.s    \LongSwitch

    ;-----------------------------------------------
    ;    Handle short switch
    ;-----------------------------------------------
\ShortSwitch:
    move.b    (a0)+,d0                ; d0.b: sign
\ShortSwitchLoop:
    addq.w    #4,d3
    move.b    (a3)+,d1
    beq.s    \NoShortSwitch
    cmp.b    (a0),d1
    beq.s    \SwitchFoundNoPop
\NoShortSwitch:
    tst.b    (a3)+                    ; CHECK THAT FOR #0 AT END OF TABLE !
    bne.s    \NoShortSwitch
    tst.b    (a3)
    bne.s    \ShortSwitchLoop
    tst.b    1(a3)
    bne.s    \ShortSwitchLoop

    ;-----------------------------------------------
    ;    Switch doesn't exist
    ;-----------------------------------------------
\InvalidSwitch:
        moveq.l #PDTLIB_INVALID_SWITCH,d0
        movea.l DATA_PTR(sp),a0
        jsr     (a2)
        moveq.l #PDTLIB_INVALID_SWITCH,d1
        bra.s   \TestCallbackReturn

    ;-----------------------------------------------
    ;    Handle long switch
    ;-----------------------------------------------
\LongSwitch:
    move.b    (a0),d4                    ; d4.b: sign
    pea    2(a0)
\LongSwitchLoop:
    addq.l    #1,a3                    ; Skip short switch
    addq.w    #4,d3
    move.l    (sp),-(sp)
    pea    (a3)
    ROMC    strcmp
    addq.l    #8,sp
    tst.w    d0
    beq.s    \SwitchFound
\SkipSwitch:
    tst.b    (a3)+
    bne.s    \SkipSwitch
    tst.b    (a3)
    bne.s    \LongSwitchLoop
    tst.b    1(a3)
    beq.s    \InvalidSwitch
    bra.s    \LongSwitchLoop

    ;-----------------------------------------------
    ;    Switch is found, execute its routine
    ;-----------------------------------------------
\SwitchFound:
        movea.l (sp)+,a0
    move.b    d4,d0
\SwitchFoundNoPop:
        movea.l SWITCHFUNC(sp,d3.w),a1
        move.l  DATA_PTR(sp),a0
        jsr     (a1)
        moveq.l #PDTLIB_SWITCH_OK,d0
        move.l  DATA_PTR(sp),a0
        jsr     (a2)
        moveq.l #PDTLIB_SWITCH_OK,d1
        bra.s   \TestCallbackReturn


(c'est moi ou les tabs sont passées à 4 caractères de large, ça chie pour la mise en page de l'asm :/)

12

Folco (./5) :
Ah ben tu poses une très bonne question au contraire, je voulais en parler mais j'ai oublié. Là j'ai du taf à faire dans la maison, mais j'ai un début d'API pour que le programme puisse être utilisé comme backend d'un GUI, c'est prévu.
cf blogs/blog.php?id=109&i=127 , une architecture comme la propose GC est plus légère, j’espère que ce sera possible avec ton prog smile

./11> De l’ASM eek et le C alors ? confus
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

13

Sasume (./12) :
cf blogs/blog.php?id=109&i=127 , une architecture comme la propose GC est plus légère, j’espère que ce sera possible avec ton prog

Pas mal, j'avais oublié son analyse. Comme dit PpHd, on est quand même sur TI, ça ferait chier de proposer une lib et un programme, alors qu'un programme kernel peut-être considéré comme une lib. Le tout est de bien choisir les points d'entrée, et de minimiser les wrappers nécessaires autour des exports pour que le programme soit appelé en tant que librairie commodément, en alourdissant au minimum le programme.

Qu'en penses-tu ?
Sasume (./12) :
./11> De l’ASM eek.gif et le C alors ? confus.gif

Tu parles pour quoi, pour les tabs ou pour le programme ? cheeky

Si c'est pour le programme, t'inquiète pas :
PDTLIB_MSG pdtlib__ManageCmdline (CMDLINE* CmdLine, void* Data, const char* SwitchList, PDTLIB_MSG (*Callback)(void* Data asm("%a0"), PDTLIB_MSG Message asm("%d0")),
                                  void (*SwitchFunc)(void* Data asm ("%a0"), char Sign asm ("%d0")), ...) __attribute__((stkparm));

Toute ma lib est appelable en C, le programme aura le même design.

14

Folco (./13) :
Comme dit PpHd, on est quand même sur TI, ça ferait chier de proposer une lib et un programme, alors qu'un programme kernel peut-être considéré comme une lib. Le tout est de bien choisir les points d'entrée, et de minimiser les wrappers nécessaires autour des exports pour que le programme soit appelé en tant que librairie commodément, en alourdissant au minimum le programme.
Qu'en penses-tu ?
Tu as tout à fait raison smile Ce qui compte c’est juste que le GUI ne fasse pas des appels à l’application en ligne de commande, mais des appels directs à l’API de ton service.
Tu parles pour quoi, pour les tabs ou pour le programme ? cheeky
Nan, c’est juste que c’est dommage que tu ne fasses pas plus de C smile
La maîtrise du 68k est probablement plus difficile à valoriser professionnellement que le C.
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

15

On m'a fait comprendre que j'aurais pas ma chance de ce côté.

Mais si tu veux voir, j'ai fait la même fonction en C : blogs/blog.php?id=400&i=36#com
Quand j'ai vu le code généré, je suis revenu à l'assembleur grin

Et il n'y a pas de support pour faire commodément des programmes read-only en C, et c'est très dommage, et je ne sais pas si j'ai le skill pour le faire, d'autant plus que ça nécessite une intégration aux toolchains existantes.

Sinon, pour l'API, j'avais commencé par exporter _main pour que le programme soit appelable par system(), mais ça fait moisi quand même grin

En fait, j'avais fait ça :
- export de _main pour un appel par system()
- accès aux messages d'erreur pour permettre de récupérer la bonne chaine à partir de la valeur retournée par le programme (donc les codes d'erreur sont documentés, et le programme appelant peut fournir l'erreur produite exacte).

Au final, ça ne serait pas suffisant ?

16

Sasume (./12) :
./11> De l’ASM eek.gif et le C alors ? confus.gif

La vie de Folco est un éternel recommencement smile
Folco (./11) :
Et tu fais comment pour différencier un fichier d'une option ?
Ou alors -xlkjsdfjherterqmsdflkjg façon tar ? C'est juste imbitable, mais bon biggrin.gif

Il faut différencier les actions / opérations principales des autres options.

17

Tiens, est-ce qu'un fichier peut commencer par un tiret sur TI ? Il y a un switch spécial ("--" si je me souviens bien) pour TAR, qui indique que ce qui suit sont des noms de fichiers et pas des options, même s'ils commencent par un tiret. (Je vous laisse chercher comment faire dans le cas où un fichier s'appelle "--", je m'en rappelle plus grin).
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

18

Non, il ne peut pas. Mais ma fonction est suffisamment bien foutue pour supporter le -- le cas échéant. cheeky
(sinon -> "truc -- --" tout simplement ?)

19

(ah ben oui, tout simplement. Ceci dit, c'est quand même un sacré bricolage, la ligne de commande hehe)
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

20

>>>>> Ceci dit, c'est quand même un sacré bricolage, la ligne de commande

T'imagine pas, surtout quand tu veux gérer des options un peu étendues qui prennent elle-même des arguments etc...
C'est pour ça que j'ai fini par faire une lib pour ça. Mon premier concept marchait, mais ne simplifiait pas assez. Maintenant, c'est aussi con que ça :
Dans le programme, tu appelles le gestionnaire (ça a l'air gros, mais en C c'est juste une ligne):
Appel
	pea	SwitchFolder(pc)
	pea	SwitchSavePath(pc)
	pea	SwitchFlash(pc)
	pea	SwitchRemove(pc)
	pea	SwitchList(pc)
	pea	SwitchUnarc(pc)
	pea	SwitchArc(pc)
	pea	SwitchCallback(pc)
	pea	StrSwitches(pc)
	clr.l	-(sp)						; a6 is used as global frame pointer, I don't need &Data
	pea	CMDLINE(a6)
	jsr	MANAGE_CMDLINE(a6)

Ensuite, tu fais une fonction par switch supporté :
Fonctions
SwitchRemove:
    move.w    #REMOVE,TASK(a6)
    moveq.l    #PDTLIB_CONTINUE,d0
    rts

SwitchFlash:
    bset.b    #FLAG_FLASH,FLAGS(a6)
    moveq.l    #PDTLIB_CONTINUE,d0
    rts

SwitchSavePath:
    bset.b    #FLAG_SAVE_PATH,FLAGS(a6)
    moveq.l    #PDTLIB_CONTINUE,d0
    rts

...

Enfin, la callback appelée après la gestion de chaque switch, en cas d'erreur, ou si un argument n'est pas un switch :
Callback
SwitchCallback:
    cmpi.w    #PDTLIB_INVALID_SWITCH,d0
    bne.s    \NotInvalidSwitch

    ;---------------------------------------------------------------
    ;    Switch doesn't exist
    ;---------------------------------------------------------------
        move.w    #ERROR_INVALID_SWITCH,ERROR(a6)
        lea    CMDLINE(a6),a0
        jsr    GET_CURRENT_ARG_PTR(a6)
        pea    (a0)
        pea    StrErrorInvalidSwitch(pc)
\QuitError:    bsr    Print2Stderr
        addq.l    #8,sp
        moveq.l    #PDTLIB_STOP,d0
        rts
\NotInvalidSwitch:
    cmpi.w    #PDTLIB_NOT_A_SWITCH,d0
    bne.s    \NotNotASwitch

...

	;---------------------------------------------------------------
	;	Else it is PDTLIB_SWITCH_OK, all is fine
	;---------------------------------------------------------------
\NotNotASwitch:
	moveq.l	#PDTLIB_CONTINUE,d0
	rts

Ca devient facile, t'as juste une fonction à écrire pour chaque chose que ton programme doit savoir faire, tu t'occupes plus de rien.
(à noter la fonction GetCurrentArgPtr pour récupérer un argument provoquant une erreur, ou un argument qui n'est pas un switch etc... GetNextArgPtr est la dernière fonction et permet de gérer les switches avec arguments (elle retourne NULL s'il n'y en a pas).

C'est beaucoup plus rapide et simple que de tout faire soi-même, et pourtant j'ai bossé un paquet de temps là-dessus !


(tiens tiens tiens... ça me fait penser que je pourrais ajouter une callback pour gérer directement les arguments qui ne sont pas des switches, en passant l'adresse de l'argument en question cheeky)
PpHd (./16) :
Il faut différencier les actions / opérations principales des autres options.

Tu pux préciser stp ? Un truc du genre :
:> par fcv -a <archive> <fichier1> <fichier 2>

Pour créer une archive (-a) de deux fichiers, la mettre en flash (f) en ignorant les erreurs (c) en mode verbeux (v)

Un truc dans ce style ?

(tiens c'est rigolo, une fonction en plus "ManagePackedSwitches()", wrapper de ManageCmdline(), et ma lib continuerait à gerér ça hehe)

21

L'emmerdement dans ce que je te propose PpHd, c'est que c'est dur d'en faire quelque chose de standard sous PedroM : en effet, les softs ne sont pas obligés d'accéder à la ligne de commande de cette manière : il peut très bien ne pas y avoir d'arguments compactés, ni de commande (pas une simple option quoi).

Avec ma lib, je voulais proposer un standard sous PedroM. Si ça ne te va pas, j'aimerais bien que tu en définisses un, je me ferai un plaisir de l'implémenter et de l'utiliser. smile

22

Folco (./20) :

Tu pux préciser stp ? Un truc du genre :
:> par fcv -a

Pour créer une archive (-a) de deux fichiers, la mettre en flash (f) en ignorant les erreurs (c) en mode verbeux (v)


Oué. Sur TI, le clavier n'est pas super pratique. Surtout pour 89.
Folco (./21) :
L'emmerdement dans ce que je te propose PpHd, c'est que c'est dur d'en faire quelque chose de standard sous PedroM : en effet, les softs ne sont pas obligés d'accéder à la ligne de commande de cette manière : il peut très bien ne pas y avoir d'arguments compactés, ni de commande (pas une simple option quoi).

Avec ma lib, je voulais proposer un standard sous PedroM. Si ça ne te va pas, j'aimerais bien que tu en définisses un, je me ferai un plaisir de l'implémenter et de l'utiliser. smile.gif

Ben le mieux serait que tu fasses des Pack Archive avec ce soft. Dans ce cas, les programmes (pour extraire) peuvent utiliser les fonctions du kernel existantes, et il ira utiliser par.
Et perso, je ferrai plutôt une interface autre que vis system("par ...") pour les softs mais directement en exportant dans par les fonctions nécessaires pour l'utiliser directement.

23

PpHd (./22) :
Oué. Sur TI, le clavier n'est pas super pratique. Surtout pour 89.

Ok, mais ça demande une double passe sur la ligne de commande.
En effet :
:> xxx fcv

Je reste dans la situation où c'est une lib qui gère la ligne de commande : Est-ce que le programme va processer le fichier fcv, ou y a-t-il une commande derrière, auquel cas fcv sont des flags ?
Et l'utilisateur peut de toutes façon avoir besoin de préfixer plusieurs options avec -, dans le cas où ses options demande des arguments (-i/--include, -f/--folder etc...).

et :
:> xxx fcv abc

Le programme doit processer deux fichiers, ou le fichier abc avec les options fcv ? A moins de normaliser ça, pour le moment c'est assez flou.
PpHd (./22) :
Ben le mieux serait que tu fasses des Pack Archive avec ce soft.

Ca nécessite donc d'utiliser zpack et zunpack. Ces programmes embarquent printf de tigcclib, c'est dommage sous PedroM où tu t'es amusé à faire une libc, d'autant plus qu'on perd stderr. Et on perd également l'exécution en archive, bref, on perd tous les avantages sur lesquels j'appuie pour les programmes dédiés à PedroM, je trouve ça dommage. Qui plus est, si on veut garder une compatibilité AMS (vu que les PA, zpack et zunpack le sont), il faut parser la ligne de commande avec les fontions de l'estack, donc on perd encore le main(int argc, const char** argv) spécifique à PedroM, et si commode. Je trouve que ça fait beaucoup de sacrifices, à moins de réimplémenter des fonctions zpack et zunpack dédiées à PedroM (entre autres en utilisant la lib système).
PpHd (./22) :
Et perso, je ferrai plutôt une interface autre que vis system("par ...") pour les softs mais directement en exportant dans par les fonctions nécessaires pour l'utiliser directement.

C'est sûrement mieux, je vais faire ça.
PpHd (./22) :
Dans ce cas, les programmes (pour extraire) peuvent utiliser les fonctions du kernel existantes, et il ira utiliser par.

Juste une question, pourquoi les programmes appelleraient-ils Par si le kernel fournit les fonctions d'extraction qui vont bien ?

Je suis un peu perplexe. En plus, à moins de rajouter un fichier d'information spécifique à Par dans le pack archive, on perd l'outil d'enregistrement/restauration de path prévu pour Par. J'ai fait ça avec dans l'idée qu'après un crash ou une fausse manip, on peut remettre sa cals d'aplomb avec un simple appel à Par, en mode --force pour écraser ce qui peut avoir été corrompu (un fichier de configuration dans /system mal modifié par l'utilisateur, et qui fait merde un soft par exemple).
En clair, je ne vois pas à quoi sert Par s'il suffit tout simplement d'utiliser zpack et zunpack qui existent déjà.

24

La capacité d'enregistrement/restauration des paths me paraît intéressante smile
Et, si "par" est un programme spécifiquement fait pour PedroM (= s'il n'a pas le but de tourner aussi sur AMS), j'aurais tendance à dire qu'à plus forte raison, s'appuyer sur les capacités spécifiques de PedroM (par rapport à AMS) décrites par Folco (libc, parsing de la ligne de commande, exécution en Flash, etc.) est la voie à suivre.
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

25

Folco (./23) :
Ca nécessite donc d'utiliser zpack et zunpack. Ces programmes embarquent printf de tigcclib, c'est dommage sous PedroM où tu t'es amusé à faire une libc, d'autant plus qu'on perd stderr. Et on perd également l'exécution en archive, bref, on perd tous les avantages sur lesquels j'appuie pour les programmes dédiés à PedroM, je trouve ça dommage. Qui plus est, si on veut garder une compatibilité AMS (vu que les PA, zpack et zunpack le sont), il faut parser la ligne de commande avec les fontions de l'estack, donc on perd encore le main(int argc, const char** argv) spécifique à PedroM, et si commode. Je trouve que ça fait beaucoup de sacrifices, à moins de réimplémenter des fonctions zpack et zunpack dédiées à PedroM (entre autres en utilisant la lib système).

Là j'avoue que je ne comprends pas pourquoi tu me parles de zpack/zunpack.
Folco (./23) :
Je reste dans la situation où c'est une lib qui gère la ligne de commande : Est-ce que le programme va processer le fichier fcv, ou y a-t-il une commande derrière, auquel cas fcv sont des flags ? Et l'utilisateur peut de toutes façon avoir besoin de préfixer plusieurs options avec -, dans le cas où ses options demande des arguments (-i/--include, -f/--folder etc...).

A toi de voir quel est le mieux. N'oublie pas la cible finale.
Folco (./23) :
Je suis un peu perplexe. En plus, à moins de rajouter un fichier d'information spécifique à Par dans le pack archive, on perd l'outil d'enregistrement/restauration de path prévu pour Par. J'ai fait ça avec dans l'idée qu'après un crash ou une fausse manip, on peut remettre sa cals d'aplomb avec un simple appel à Par, en mode --force pour écraser ce qui peut avoir été corrompu (un fichier de configuration dans /system mal modifié par l'utilisateur, et qui fait merde un soft par exemple). En clair, je ne vois pas à quoi sert Par s'il suffit tout simplement d'utiliser zpack et zunpack qui existent déjà.

Ok, comme tu veux. Ce n'était qu'une proposition.

26

PpHd (./25) :
Là j'avoue que je ne comprends pas pourquoi tu me parles de zpack/zunpack.

Parce que c'est le seul moyen que je connaisse de créer un pack archive on-calc (hormis le fait de recoder ça from scratch évidemment).
PpHd (./25) :
A toi de voir quel est le mieux. N'oublie pas la cible finale.

C'est vrai, j'y avais pas pensé avec les options longues. grin

27

API

unsigned short par__ArchiveFile (const char* Archive, unsigned short Flags, const char* Folder, const char* File1, ...);
unsigned short par__ExtractFile (const char* Archive, unsigned short Flags, const char* Folder, const char* File1, ...);
unsigned short par__Remove      (const char* Archive, const char* File1, ...);
unsigned short par__List        (const char* Archive, const char* File1, ...);

Tiens, vous en pensez quoi de ça ? Ca m'a l'air tout couillon en fait...

Un programme peut appeler la lib en lui passant un nom d'archive, les flags, et une va_list des fichiers à traiter. Le dernier argument de la va_list est NULL.
Le programme en lui-même est un wrapper qui va juste recréer ça pour faire des appels internes à ses propres exports.
Les noms de fichiers sont à passer sous forme de C-string, parce que c'est toujours casse-bonbons de créer des SYM_STR et de les vérifier.

Ca a pas l'air trop con ? cheeky

28

Tu peux préciser comment ca marche ? Ce n'est pas très clair.
Par exemple pour extraire une archive sans savoir quels sont les fichiers dedans on fait comment ?
Pour lister une archive ?
C'est quoi les valeurs retours retournées ?

29

PpHd (./28) :
Par exemple pour extraire une archive sans savoir quels sont les fichiers dedans on fait comment ?

D'une manière générale, l'opération à faire sur l'archive (extraction, listing, suppression) se fait sur tous les fichiers de l'archive, sauf si une liste de fichiers est précisée, auquel cas l'opération s'applique à cette liste. Il suffit de passer NULL comme seul argument de la va_list pour que celle-ci soit vide.

'par__ExtractFile (<archive>, <Flags>, NULL);' extrait tous les fichiers d'une archive.
PpHd (./28) :
C'est quoi les valeurs retours retournées ?

Bonne question, je me rends compte que je ne peux pas me contenter d'un code d'erreur : ce n'est pas assez précis, notamment dans le cas où le programme veut signaler quel est le fichier manquant, ou au nom invalide etc : Par sait en temps réel quel fichier provoque l'erreur (et s'en sert pour afficher 'invalid file %s' par exemple), mais cette info est perdue lorsqu'on retourne au programme appelant.

Le mieux serait peut-être de renvoyer un handle au format documenté, genre :
; header
ds.b 2 -> code d'erreur
ds.b (strlen(str)) -> chaine d'erreur (word null si pas d'erreur)

; Pour list, on rajoute :
ds.b 2 -> nombre de fichiers

; Puis une partie dynamique :
ds.b 18 -> Nom du fichier (c-string)
ds.b 2 -> taille du fichier
ds.b 1 -> type
ds.b 1 -> <padding>
etc...
dc.w 0 -> fin de la liste.

A charge pour le programme appelant de libérer le handle évidemment.

De plus, si on veut qu'un programme type GUI ait accès aux infos du mode verbveux ou aux erreurs non fatales (option -c -> continue sur les erreurs quand c'est possible), il faut que Par puisse appeler une callback, afin que le programme puisse afficher cette chaine (dans le terminal, dans une fenêtre...).

Ca donne donc des protos de ce genre :
HANDLE par__ArchiveFiles (const char* Archive, unsigned short Flags, void (*Callback) (const char* Str), const char* Folder, const char* File1, ...);
HANDLE par__ExtractFiles (const char* Archive, unsigned short Flags, void (*Callback) (const char* Str), const char* Folder, const char* File1, ...);
HANDLE par__Remove (const char* Archive, void (*Callback) (const char* Str), const char* File1, ...);
HANDLE par__List (const char* Archive, void (*Callback) (const char* Str), const char* File1, ...);



Note : Si la callback vaut null, alors stdout/err sont utilisés comme sortie.
En effet, le programme Par est un wrapper autour de la lib (puisqu'il est aussi une lib cheeky), et s'appelle comme n'importe quel programme externe (à la différence près qu'il fait un bsr vers ses propres fonctions exportées évidemment).

En clair, _main parse la ligne de commande, construit les appels vers par@000x, puis fait l'appel.
Plus qu'un programme qui exporte des services, Par devient un wrapper autour d'une librairie. Ca simplifie de beaucoup le code amha.

30

Cette bibliothèque risque d'être difficile à utiliser avec ces listes d'argument et les valeurs de retour non directes...

Peut-être que tu pourrais ajouter des fonctions plus simples à utiliser, tout en conservant les autres si tu trouves qu'elles ont leur intérêt.
Il pourrait y avoir :
unsigned short par__ArchiveFile(const char *Archive, unsigned short Flags, const char *Folder, const char *File);
unsigned short par__ExtractFile(const char *Archive, unsigned short Flags, const char *Folder, const char *File);
unsigned short par__Remove(const char *Archive, const char *File);

J'ai gardé les mêmes noms, je pense qu'il faudrait renommer les fonctions agissant sur des va_list smile
avatar