home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / e / amigae30a_fr.lha / AmigaE30f / Sources / Utils / D.e < prev    next >
Encoding:
Text File  |  1994-10-03  |  11.2 KB  |  296 lines

  1. /* outils récursifs de répertoire
  2.  
  3. A besoin de la v37.
  4.  
  5. Afficheur universel de répertoire. Appelé sans arguments, et tapant juste
  6. "d", il liste le répertoire courant. Arguments:
  7.  
  8. DIR,REC/S,COL/K/N,SIZE/S,NOSORT/S,NOFILES/S,NODIRS/S,FULL/S,NOANSI/S,
  9. TARGET/K,DO/K/F
  10.  
  11. DIR             spécifie un chemin optionnel au répertoire que vous voulez lister.
  12.                 il peut contenir des caractères génériques standards comme #?~[]%() etc.
  13. REC             spécifie que les sous-répertoire doivent être listés récursivement.
  14. COL <num>       où n=1..3, par défaut, D liste les répertoires en 3 colonnes.
  15.                 le tout bien mignon et compact. spécifie 1 ou 2 si vous voulez.
  16. SIZE            reporte la taille de chaque répertoire lors de l'affichage.
  17.                 Notez que combiné avec REC, ça donne le taille de tout le répertoire
  18.                 et des sous répertoires.
  19. NOSORT          par défaut, les répertoires sont triés avant l'affichage.
  20.                 Mettez cette option hors service avec NOSORT.
  21. NOFILES         affiche juste les répertoires.
  22. NODIRS          affiche juste les fichiers.
  23. FULL            met le chemin entier au lieu des fichiers juste.
  24. NOANSI          n'utilise pas l'affichage ansi lors de l'impression.
  25. TARGET <dir>    spécifie le répertoire destination pour l'utilisation avec DO.
  26.                 le répertoire doit se terminer pas "/" ou ":"
  27. DO <comline>    spécifie la ligne de commande pour la génération automatique
  28.                 des scripts. Notez que celui utilise toute la fin de la ligne.
  29.  
  30. Je doit dire quelquechose à dire sur les caractèristiques des scripts: ils
  31. permettent de faire des taches répétitives sur des répertoires, ou des arbres-
  32. répertoires. Les utilitaires éxistant qui vous permettent ce type de tache, ne
  33. sont pas assez souple ; D vous permet d'utiliser le mot REC en combinaison avec
  34. les scripts, accepte des extensions variables: utilisez <fichier>.o si le nom
  35. original est <fichier>.s, et le chemin de destination: les fichiers créés par
  36. l'opération sont placés dans un autre répertoire qui peut être une image d'un
  37. autre arbre-répertoire. Les commandes 'makedir' sont insérés si la destination
  38. est vide.
  39.  
  40. Les formats suivant peuvent être utilisé dansla ligne de commande:
  41.  
  42. %s est le fichier (chemin et nom)
  43. %f est le fichier SANS extension
  44. %r est le fichier sans extension, mais un <dir> remplacé par <target>
  45.    (utile si <ligne de commande> permet un fichier de sortie)
  46. %> ou %< %>> etc. prévients le shell de croire que ">" is une redirection
  47.    pour D, au lieu de <ligne de commande>
  48.  
  49. Un exemple complexe:
  50. Vous voulez avoir une référence complète ascii du répertoire emodules:,
  51. récursivement, et avec un fichier .txt créé comme une structure répertoire
  52. image quelque part.
  53.  
  54. 1> D >ram:script emodules: REC TARGET=t:mods/ DO showmodule %>%r.txt %s
  55. 1> execute ram:script
  56.  
  57. le fera pour vous.
  58. POur tous les fichiers du type "emodules:exec/io.m" D fera uneligne du style:
  59. "showmodule  >t:mods/exec/io.txt emodules:exec/io.m"
  60.  
  61. autres exemples: D >mydirlist dh0: COL=2 SIZE REC NOANSI
  62.                  D docs: DO type >prt: %s
  63.                  D asm: TARGET=obj: DO genam %s -o%r.o
  64.                  D emodules: REC TARGET=ram: DO showmodule %>%r.txt %s
  65.  
  66.  
  67. BUGS:
  68.  y en a plus.
  69.  
  70. AMéLIORATIONS PAR RAPPORT AU VIEUX "D"
  71. - beaucoup plus rapide
  72. - récursif
  73. - calcule la taille des fichiers d'arbres d'un répertoire entier
  74. - une, deux, trois colonnes
  75. - caractères génériques (? * #?)
  76. - meilleur tri, et plus rapide
  77. - meilleur code : gère les répertoire de toutes les tailles
  78. - un tas d'option grace au standard readargs()
  79. - génération puissant de script
  80. - utilise des gestionnaires d'exception imbriqués pour pister les appels
  81.   MatchEnd() lors d'un CtrlC ou un erreur soudaine.
  82.  
  83. */
  84.  
  85. OPT OSVERSION=37
  86.  
  87. CONST MAXPATH=250
  88.  
  89. ENUM ER_NONE,ER_BADARGS,ER_MEM,ER_UTIL,ER_ITARG,ER_COML
  90. ENUM ARG_DIR,ARG_REC,ARG_COL,ARG_SIZE,ARG_NOSORT,ARG_NOFILES,
  91.      ARG_NODIRS,ARG_FULL,ARG_NOANSI,ARG_TARGET,ARG_COMMAND,NUMARGS
  92.  
  93. MODULE 'dos/dosasl', 'dos/dos', 'utility'
  94.  
  95. RAISE ER_MEM IF New()=NIL,        /* fixe les exceptions habituelles:      */
  96.       ER_MEM IF String()=NIL,     /* chaque appel à ces fonction seront    */
  97.       ERROR_BREAK IF CtrlC()=TRUE /* automatiquement vérifié vis à vis de  */
  98.                                   /* NIL et l'exception ER_MEM est levée   */
  99.  
  100. DEF dir,command,target,
  101.     recf=FALSE,col=3,comf=FALSE,sizef=FALSE,sortf=TRUE,filesf=TRUE,
  102.     fullf=FALSE,ansif=TRUE,dirsf=TRUE,dirw[100]:STRING,
  103.     rdargs=NIL,work[250]:STRING,work2[250]:STRING,dirno=0,
  104.     prtab[25]:LIST,prcopy[25]:LIST,workdir[250]:STRING
  105.  
  106. PROC main() HANDLE
  107.   DEF args[NUMARGS]:LIST,templ,x,lock,fib:fileinfoblock,s
  108.   IF (utilitybase:=OpenLibrary('utility.library',37))=NIL THEN Raise(ER_UTIL)
  109.   FOR x:=0 TO NUMARGS-1 DO args[x]:=0
  110.   templ:='DIR,REC/S,COL/K/N,SIZE/S,NOSORT/S,NOFILES/S,NODIRS/S,' +
  111.          'FULL/S,NOANSI/S,TARGET/K,DO/K/F'
  112.   rdargs:=ReadArgs(templ,args,NIL)
  113.   IF rdargs=NIL THEN Raise(ER_BADARGS)          /* initialise les drapeaux */
  114.   IF args[ARG_SIZE] THEN sizef:=TRUE       /* des arguments de la commande */
  115.   IF args[ARG_COL] THEN col:=Long(args[ARG_COL])
  116.   IF args[ARG_NOSORT] THEN sortf:=FALSE
  117.   IF args[ARG_NOANSI] THEN ansif:=FALSE
  118.   IF args[ARG_NOFILES] THEN filesf:=FALSE
  119.   IF args[ARG_NODIRS] THEN dirsf:=FALSE
  120.   IF args[ARG_REC] THEN recf:=TRUE
  121.   IF args[ARG_FULL] THEN fullf:=TRUE
  122.   target:=args[ARG_TARGET]
  123.   command:=args[ARG_COMMAND]
  124.   IF command THEN comf:=TRUE
  125.   IF (col<>1) AND (col<>2) THEN col:=3
  126.   IF target
  127.     x:=target+StrLen(target)-1
  128.     IF (x<target) OR ((x[]<>":") AND (x[]<>"/")) THEN Raise(ER_ITARG)
  129.   ENDIF
  130.   IF comf
  131.     sortf:=FALSE        /* lit et convertis la commande pour les scripts */
  132.     col:=1
  133.     filesf:=FALSE
  134.     dirsf:=FALSE
  135.     IF command[]=0 THEN Raise(ER_COML)
  136.     s:=command
  137.     WHILE x:=s[]++
  138.       IF x="%"
  139.         x:=s[]
  140.         SELECT x
  141.           CASE "s"; ListAdd(prtab,[1],1)                    /* %s = chemin entier */
  142.           CASE "f"; ListAdd(prtab,NEW [work],1); s[]:="s"   /* %f = work     */
  143.           CASE "r"; ListAdd(prtab,NEW [work2],1); s[]:="s"  /* %r = work2    */
  144.           DEFAULT; s[-1]:=" "
  145.         ENDSELECT
  146.       ENDIF
  147.     ENDWHILE
  148.   ENDIF
  149.   dir:=args[ARG_DIR]
  150.   IF dir THEN StrCopy(dirw,dir,ALL)
  151.   lock:=Lock(dirw,-2)
  152.   IF lock                  /* si oui, le rép prob., sinon car. générique */
  153.     IF Examine(lock,fib) AND (fib.direntrytype>0)
  154.       AddPart(dirw,'#?',100)
  155.     ENDIF
  156.     UnLock(lock)
  157.   ENDIF
  158.   recdir(dirw)
  159.   Raise(ER_NONE)
  160. EXCEPT
  161.   IF rdargs THEN FreeArgs(rdargs)
  162.   IF utilitybase THEN CloseLibrary(utilitybase)
  163.   SELECT exception
  164.     CASE ER_BADARGS;            WriteF('Mauvais Arguments pour D!\n')
  165.     CASE ER_MEM;                WriteF('Pas de mémoire!\n')
  166.     CASE ER_COML;               WriteF('Pas de ligne de commande spécifié\n')
  167.     CASE ER_ITARG;              WriteF('Cible illégale\n')
  168.     CASE ER_UTIL;               WriteF('Nepeut pas ouvrir l''"utility.library" v37\n')
  169.     CASE ERROR_BREAK;           WriteF('Arrêt de D par l'utilisateur\n')
  170.     CASE ERROR_BUFFER_OVERFLOW; WriteF('Erreur interne\n')
  171.     DEFAULT;                    PrintFault(exception,'Dos Error')
  172.   ENDSELECT
  173. ENDPROC
  174.  
  175. PROC recdir(dirr) HANDLE
  176.   DEF er,i:PTR TO fileinfoblock,size=0,anchor=NIL:PTR TO anchorpath,fullpath,
  177.       flist=NIL,first,entries=0,sortdone,next,nnext,prev,ascii,x,y,flist2=NIL,
  178.       esc1,esc2,ds:PTR TO LONG,isfirst=0
  179.   anchor:=New(SIZEOF anchorpath+MAXPATH)
  180.   anchor.breakbits:=4096
  181.   anchor.strlen:=MAXPATH-1
  182.   esc1:=IF ansif THEN '\e[1;32m' ELSE ''
  183.   esc2:=IF ansif THEN '\e[0;31m' ELSE ''
  184.   ds:=['\s\l\s[50]\s <dir>','\l\s[47] \r\d[8]','\s\l\s[30]\s <dir>','\l\s[27] \r\d[8]','\s\l\s[19]\s <dir>','\l\s[17] \r\d[7]']
  185.   er:=MatchFirst(dirr,anchor)                   /* collecte les chaines */
  186.   WHILE er=0
  187.     fullpath:=anchor+SIZEOF anchorpath
  188.     i:=anchor.info
  189.     ascii:=IF fullf THEN fullpath ELSE i.filename
  190.     IF i.direntrytype>0 THEN StringF(work,ds[col-1*2],esc1,ascii,esc2) ELSE StringF(work,ds[col-1*2+1],ascii,i.size)
  191.     IF IF i.direntrytype>0 THEN dirsf ELSE filesf
  192.       first:=String(EstrLen(work))
  193.       StrCopy(first,work,ALL)
  194.       flist:=Link(first,flist)
  195.       INC entries
  196.     ENDIF
  197.     IF i.direntrytype<0 THEN size:=size+i.size
  198.     IF (i.direntrytype<0) AND comf              /* éxécute la ligne de cmd */
  199.       ListCopy(prcopy,prtab,ALL)
  200.       IF comf THEN MapList({x},prcopy,prcopy,`IF x=1 THEN fullpath ELSE x)
  201.       StrCopy(work,fullpath,ALL)
  202.       x:=InStr(work,'.',0)
  203.       IF x<>-1 THEN SetStr(work,x)              /* trouve f% */
  204.       IF target
  205.         StrCopy(work2,target,ALL)
  206.         x:=work; y:=dirw        /* was dirr */
  207.         WHILE x[]++=y[]++ DO NOP
  208.         DEC x
  209.         StrAdd(work2,x,ALL)                     /* trouve r% */
  210.       ELSE
  211.         StrCopy(work2,work,ALL)
  212.       ENDIF
  213.       IF isfirst++=0
  214.         StrCopy(workdir,work2,ALL)      /* regarde si makedir est nécessaire */
  215.         SetStr(workdir,PathPart(work2)-work2)
  216.         x:=Lock(workdir,-2)
  217.         IF x THEN UnLock(x) ELSE WriteF('makedir \s\n',workdir)
  218.       ENDIF
  219.       Flush(stdout); VfPrintf(stdout,command,prcopy); Flush(stdout)
  220.       WriteF('\n')
  221.     ENDIF
  222.     IF recf AND (i.direntrytype>0)              /* fait la récursion(=tail) */
  223.       x:=StrLen(fullpath)
  224.       IF x+5<MAXPATH THEN CopyMem('/#?',fullpath+x,4)
  225.       size:=size+recdir(fullpath)
  226.       fullpath[x]:=0
  227.     ENDIF
  228.     er:=MatchNext(anchor)
  229.   ENDWHILE
  230.   IF er<>ERROR_NO_MORE_ENTRIES THEN Raise(er)
  231.   MatchEnd(anchor)
  232.   Dispose(anchor)
  233.   anchor:=NIL
  234.   flist:=Link(String(1),flist)
  235.   IF entries>2 AND sortf
  236.     REPEAT
  237.       sortdone:=TRUE                            /* tri de la liste de rép */
  238.       prev:=first:=flist
  239.       WHILE first:=Next(first)
  240.         IF next:=Next(first)
  241.           IF Stricmp(first,next)>0
  242.             nnext:=Next(next)
  243.             Link(prev,first:=Link(next,Link(first,nnext)))
  244.             sortdone:=FALSE
  245.           ENDIF
  246.         ENDIF
  247.         CtrlC()
  248.         prev:=first
  249.       ENDWHILE
  250.     UNTIL sortdone
  251.   ENDIF
  252.   IF col>1                                    /* met lalist de rép en colonne */
  253.     x:=entries/col
  254.     IF x*col<entries THEN INC x
  255.     first:=Next(flist)
  256.     next:=Forward(first,x)
  257.     nnext:=IF col=3 THEN Forward(next,x) ELSE NIL
  258.     flist2:=Link(String(1),flist2)
  259.     prev:=flist2
  260.     WHILE first AND (x-->=0)
  261.       StrCopy(work,first,ALL)
  262.       IF next
  263.         StrAdd(work,' ',1)
  264.         StrAdd(work,next,ALL)
  265.         IF nnext
  266.           StrAdd(work,' ',1)
  267.           StrAdd(work,nnext,ALL)
  268.         ENDIF
  269.       ENDIF
  270.       ascii:=String(EstrLen(work))
  271.       StrCopy(ascii,work,ALL)
  272.       Link(prev,prev:=ascii)
  273.       first:=Next(first)
  274.       IF next THEN next:=Next(next)
  275.       IF nnext THEN nnext:=Next(nnext)
  276.     ENDWHILE
  277.     DisposeLink(flist)
  278.     flist:=flist2
  279.   ENDIF
  280.   IF comf=FALSE                                         /* affiche le rép */
  281.     IF dirno THEN WriteF('\n')
  282.     WriteF(IF ansif THEN '\e[1mRépertoire de: "\s"\e[0m\n' ELSE 'Répertoire de: "\s"\n',dirr)
  283.   ENDIF
  284.   first:=flist
  285.   WHILE first:=Next(first)
  286.     WriteF('\s\n',first)
  287.     CtrlC()
  288.   ENDWHILE
  289.   IF sizef THEN WriteF('BYTE SIZE: \d\n',size)
  290.   DisposeLink(flist)
  291.   INC dirno
  292. EXCEPT                                  /* gestionnaire d'exception! */
  293.   IF anchor THEN MatchEnd(anchor)
  294.   Raise(exception)  /* Comme ça on peut appeler _tous_ les gestionnaires dans la récursion  */
  295. ENDPROC size        /* et donc appeler MatchEnd() sur tousles 'anchors' */
  296.