%==========================================================================
\Chapter {2} {L'Analyseur de Modules}
%==========================================================================

L'{\em Analyseur de Modules} est un utilitaire servant \`{a} d\'{e}terminer la
description d'un module et, en particulier, \`{a} d\'{e}terminer la liste
des fonctions qui doivent \^{e}tre export\'{e}es par ce module, ainsi
que la liste des autres modules devant \^{e}tre import\'{e}s afin qu'il soit
correctement compil\'{e} par \|complice| (cf chapitre 13
du manuel \LeLisp ).

%---------------------------------------------------------------------------
\Section {Principe de fonctionnement}
%---------------------------------------------------------------------------

L'{\em Analyseur de Modules} travaille \`{a} l'aide du {\bf projet} et
engendre ou modifie un fichier descripteur de module
(fichier {\tt .lm}).

Il charge les fichiers source indiqu\'{e}s dans la rubrique {\tt files}
du module et les analyse, c'est-\`{a}-dire qu'il recense toutes les fonctions et
autres entit\'{e}s pr\'{e}sentes dans le code et d\'{e}tecte les
autres modules \LeLisp\ exportant/d\'{e}finissant ces fonctions/entit\'{e}s.

Pour ce module, il d\'{e}duit la liste des modules \`{a} importer (clef
\|import|) et les fonctions \`{a} exporter (clef \|export|).

Il compare ces listes avec celles \'{e}ventuellement mentionn\'{e}es par le
programmeur dans 
le descripteur de module.  Il propose alors des ajouts et des retraits
\`{a} cette liste et justifie ses choix.

Un {\tt Makefile} d'analyse peut \^{e}tre engendr\'{e} afin d'automatiser ce
travail sur l'ensemble des modules du projet.

Une fois que tous les modules d'un projet sont g\'{e}n\'{e}r\'{e}s,
l'analyseur peut engendrer un {\tt Makefile} de compilation afin d'aider le
programmeur \`{a} compiler ces modules avec {\tt complice} (l'adoption du
module {\tt mms} sous VMS, ou du module {\tt Makefile} sous DOS est
obligatoire pour ce trait).

%---------------------------------------------------------------------------
\Section {D\'{e}finition d'un projet}
%---------------------------------------------------------------------------

Cette section d\'{e}crit la mani\`{e}re d'\'{e}crire un projet. 
On utilise pour cela un {\it fichier de projet} du type {\tt <project>.prj}.
C'est dans ce fichier qu'on trouvera toutes les formes
n\'{e}cessaires \`{a} la d\'{e}finition d'un projet,
les fonctions de cr\'{e}ation et de manipulation
d'un projet. C'est \'{e}galement dans ce fichier qu'on chargera
\'{e}ventuellement d'autres projets (cf. clef \|required-project|).

Les projets des produits \Ilog\
sont d\'{e}finis dans les r\'{e}pertoires \|modana| de chaque produit, dans
le fichier projet du produit: 
\|/usr/ilog/<product>/modana/<product>.prj|. On trouvera ainsi pour
les principaux produits Ilog\,:
\begin{Code*}
/usr/ilog/lelisp/modana/lisp.prj
/usr/ilog/aida/modana/aida.prj
/usr/ilog/smeci/modana/smeci.prj
/usr/ilog/rpc/modana/rpc.prj
 ...
\end{Code*}

Un certain nombre de fonctions sont fournies afin de d\'{e}finir/g\'{e}rer
les projets, la forme de d\'{e}finition de projet {\tt define-rt-project}
\'{e}tant la plus importante. Se reporter au chap\^{\i}tre 6 sur les extensions de
l'analyseur pour plus de pr\'{e}cisions sur les autres formes cens\'{e}es
appara\^{\i}tre dans le fichier de projet. On notera en particulier
l'existence d'une forme de d\'{e}finition de groupe de
projets ({\tt define-rt-group-project}), d'un "d\'{e}finisseur de
d\'{e}finisseur" ( {\tt defdefiner}), et d'un d\'{e}finisseur de 
forme dynamique ({\tt defdynamic}) etc. \\

\SSection {Les principales clefs d'une d\'{e}finition de projet}
%---------

\|define-rt-project| permet de d\'{e}finir un projet nomm\'{e}.  Ce nom
permet de r\'{e}f\'{e}rencer le projet dans un autre projet (via
\|required-project|). Plusieurs projets
sont ainsi d\'{e}finis pour les produits \Ilog, mais l'utilisateur peut
d\'{e}finir ses propres projets.  

%****************************************************************************
\Macro {define-rt-project} {name key1 val1 keyn valn} {N}
%****************************************************************************

La macro \|define-rt-project| impose au moins un nom de projet en
premier argument. Un certain nombre de clefs sont disponiles pour d\'{e}crire
compl\`{e}tement le projet. Seules les principales options sont d\'{e}crites
dans la d\'{e}finition qui suit. Pour une description exhaustive
de l'ensemble des clefs, se reporter au chap\^{\i}tre 5.
La macro \|define-rt-project| n'\'{e}value pas ses arguments. 
Les clefs principales de cette macro sont les suivantes\,:

\begin{itemize}

\item {\Large \|root-directory| {\em path}}: le r\'{e}pertoire ``racine{''} 
du projet \|name|. L'utilisation de cette clef
permet de sp\'{e}cifier des chemins relatifs pour les autres clefs de
r\'{e}pertoires telles que \|directories|, \|system-directory| ou
\|crunch-directory|. 
Lorsque cette clef est omise, il faut sp\'{e}cifier les autres clefs de
d\'{e}finition de r\'{e}pertoires
avec des chemins absolus. Pour \LeLisp :

\begin{Code*}
  root-directory #u"/usr/ilog/lelisp/"
\end{Code*}

On \'{e}tudiera \'{e}galement les clefs \|system-directory| et
\|crunch-directory| (voir chap\^{\i}tre 5) pour ranger les fichiers
syst\`{e}me de l'analyseur.

\item {\Large \|directories| {\em list}}: pour sp\'{e}cifier la liste des
r\'{e}pertoires qui contiennent les sources et/ou les modules du projet
\|name|. 
Cette liste de r\'{e}pertoires met \`{a} jour le contenu de la
variable syst\`{e}me \LeLisp\ {\tt \#:system:path}. Cette liste ne peut
pas \^{e}tre vide. Ces chemin peuvent \^{e}tre relatifs \`{a} {\tt root-directory}.
Par exemple, 
pour \LeLisp\ sur sun4\,:

\begin{Code*}
  directories ("sun4/"
               "llib/"
               "llmod/"
               "llobj/"
               "llub/"
               )
\end{Code*}

\begin{Side}{\bf Remarque}
l'{\em Analyseur de Modules} v\'{e}rifie l'existence des
r\'{e}pertoires sp\'{e}cifi\'{e}s par la clef \|directories|. 
Si un r\'{e}pertoire n'existe pas, il imprime un message du
type:
\BeginLL
** check-directory : directory doesn't exist: looks/simplelook/
\EndLL
\end{Side}

On \'{e}tudiera \'{e}galement les clefs \|ll-module-directory| et
\|ll-object-directory| (voir chap\^{\i}tre 5) pour g\'{e}rer plus finement
les fichiers de 
module et leur compilation.

\item {\Large \|required-projects| {\em list}}: les
``sous-projets{''} qui sont 
n\'{e}cessaires \`{a} l'utilisation de ce projet. La valeur de cette clef
est une liste de symboles d\'{e}signant les noms des projets requis. Par
exemple\,:

\begin{Code*}
(define-rt-project smeci
   required-projects (smstr)
   ...)
\end{Code*}

\begin{Side}{\bf Remarque}
On prendra \'{e}ventuellement soin de charger les
fichiers qui d\'{e}finissent les projets requis par \|required-project|.
Par exemple, si on utilise les librairies \LeLisp\ et \Aida\,:
\end{Side}
\begin{Code*}
% cat myproject.prj
^L/usr/ilog/lelisp/modana/lisp.prj
^L/usr/ilog/aida/modana/aida.prj

(define-rt-project myproject
 ...
\end{Code*}

\item {\Large \|modules-lists| {\em list}}: cette clef est
destin\'{e}e \`{a} informer 
pr\'{e}cis\'{e}ment le projet sur les modules \`{a} traiter. Par d\'{e}faut, on
construit les tables 
destin\'{e}es \`{a} l'{\em Analyseur de Modules} \`{a} partir de tous les modules
({\tt *.lm})
contenus dans les r\'{e}pertoires de la clef
\|directories|. Mais si \|modules-lists| existe, elle permet de
sp\'{e}cifier une liste de fichiers ({\tt *.lst}) contenant la liste des modules
composant le projet. Les fichiers ({\tt *.lst})  ainsi r\'{e}f\'{e}renc\'{e}s
par \|modules-lists| 
sont recherch\'{e}s dans chacun des 
r\'{e}pertoires de la clef \|directories| ou \|ll-module-directory|.
Par exemple, pour analyser le produit
\Masai2d\ (dont le nom de projet est {\tt maida2d}),
on a sp\'{e}cifi\'{e} la liste
des modules \`{a} prendre dans des fichiers \|modules.lst| r\'{e}partis 
dans chacun des r\'{e}pertoires sp\'{e}cifi\'{e}s par la clef \|directories|\,:

\begin{Code*}
(define-rt-project maida2d
        root-directory #p"/usr/ilog/maida2d/"
        required-projects (aida)  
        directories (#u"src/")
        modules-lists ("modules.lst")
        crunch-directory #u"modana/"
        ...)
\end{Code*}

Dans chaque r\'{e}pertoire de la clef \|directories|, on d\'{e}finit un
fichier \|modules.lst|. Par exemple\,:

\begin{Longcode*}
% cat /usr/ilog/maida2d/src/modules.lst
floatdraw
m2-macro
m2-object
m2-point
m2-bbox
m2-transfor
m2-screen
...
\end{Longcode*}

On \'{e}tudiera \'{e}galement les clefs \|modules| et \|modules-files| pour
g\'{e}rer compl\`{e}tement les noms des fichiers.

\begin{Side}{\bf Remarque}
Si aucun des fichiers 
sp\'{e}cifi\'{e}s avec la clef \|modules-list| ne figure dans un r\'{e}pertoire
donn\'{e} par la cl\'{e} \|directories| alors tous les 
modules de {\em ce r\'{e}pertoire} sont pris en compte pour construire
les tables d'analyse.
\end{Side}

\item {\Large \|module-extension| {\em string}}: cette clef, si
elle existe, 
contient une cha\^{\i}ne de caract\`{e}res qui
d\'{e}signe l'extension utilis\'{e}e pour sp\'{e}cifier le nom du fichier
source du module. Si l'utilisateur
d\'{e}sire conserver une version de ses fichiers de descriptions modulaires, non
``pollu\'{e}e {''} par {\tt complice} (rappel\,: {\tt complice} \'{e}crit ses
propres informations dans les fichiers de description modulaire), il
choisira une nouvelle extension de fichier diff\'{e}rente de {\tt
"lm"}, afin de cr\'{e}er un nouveau fichier. On choisit habituellement
l'extension {\tt "lc"}. \\
Cette clef est exploit\'{e}e par les options \|-init|, \|-makefile| et
\|-build| de l'{\em Analyseur de Modules}.
Les {\tt Makefile} engendr\'{e}s avec ces options utilisent alors
les {\tt "lc"} comme point de d\'{e}part. On se reportera au chapitre 5
pour une discussion d\'{e}taill\'{e}e.

\end{itemize}

\SSection {Exemples}
Voici quelques exemples de d\'{e}finitions de projets. On trouvera 
respectivement les
projets correspondant au Bitmap Virtuel, et \`{a} la librairie \LeLisp\,:


\begin{Longcode*}
;;; all using LL directories
(setq MODANA #.(catenate #:system:directory "modana/"))
(setq LLIB   #:system:llib-directory)
(setq LLUB   #:system:llub-directory)
(setq SYSTEM #:system:system-directory)
(setq LLMOD  #:system:llmod-directory)
(setq LLOBJ  #:system:llobj-directory)
(setq X11    #.(catenate #:system:virbitmap-directory "X11/"))

;;; sub-project for Bitmap Virtuel : X11
(setq x11.prj
(define-rt-project x11
  root-directory \#.MODANA
  directories (\#.X11 \#.LLMOD)
  required-projects (lisp)
  project-file #p"lisp.prj"
  modules-lists (#p"virx11.lst")
))
\end{Longcode*}


Dans ce projet \|x11|, deux r\'{e}pertoires sont cens\'{e}s contenir tous
les sources\,: {\tt X11} et {\tt LLMOD}.

Le projet principal \|lisp|\,:


\begin{Longcode*}
;;; main project, including LL library
(setq lisp.prj
(define-rt-project lisp
  root-directory \#.MODANA
  directories (\#.SYSTEM
               \#.LLIB
               \#.LLOBJ
               \#.LLMOD
               \#.LLUB)
  required-projects ()
  modules-lists (llib.lst llub.lst system.lst llmod.lst)
))
\end{Longcode*}

Dans la d\'{e}finition du projet \|lisp|, l'ensemble des noms des
fichiers source seront trouv\'{e}s dans les fichiers {\tt llib.lst,
llub.lst} et {\tt system.lst} r\'{e}partis dans l'ensemble des
r\'{e}pertoires du champ \|directories|. En r\'{e}alit\'{e} l'analyseur
commence par r\'{e}unir tous les fichiers list\'{e}s dans tous les fichiers
{\tt llib.lst} de tous les r\'{e}pertoires du projet, puis tous les
fichiers contenus dans les fichiers {\tt llub.lst} de tous les
r\'{e}pertoires du projet, puis tous les fichiers {\tt system.lst} de
tous les r\'{e}pertoires du projet. Le fichier {\tt llmod.lst} \'{e}tant
volontairement vide.

Nous terminons la pr\'{e}sentation compl\`{e}te du projet \|lisp|,
avec des formes d'utilisation avanc\'{e}e de l'analyseur et du compilateur,
qui sont d\'{e}crites au chapitre 6\,:

\begin{Longcode*}
;;; defined new definers for ANALYZER
;; macro-character
(defdefiner dmc)

;; splice-macro
(defdefiner dms)

;; DEFABBREV, DEFSHARP are already declared with DEFDEFINER inside analyzer 
\end{Longcode*}


L'exemple d'\Aida, dans lequel on trouvera respectivement les projets 
de la librairie \Aida\ de base, des modules tels que
\|grapher| et \|hypertext|, ainsi que bien
d'autres modules ou sous-projets, est plus complexe car il fait appel
\`{a} la notion de groupes de projets\,:

\begin{Longcode*}
(eval-when (load eval compile)
   (defvar rt-aida-directory #u"/usr/ilog/aida/")

;;;;;;;
;;; Basic Aida Kernel
;;;;;;;

(define-rt-project mdakerne
  required-projects (lisp)
  root-directory #.rt-aida-directory
  system-directory #u"modana/"
  crunch-directory #u"modana/crunchdb/"
  activate-function aida-activate-func
  directories (#u"modules/")
  project-file "aida.prj"
  )

...
...
...

;;;;;;
;;; Tools
;;;;;;

(define-rt-project mdatools
  required-projects (mdakerne)
  root-directory #.rt-aida-directory
  system-directory #u"modana/"
  crunch-directory #u"modana/crunchdb/"
  directories (#u"modules/")
  project-file "aida.prj"
  )

...
...
...

;;;;;;
;;; Grapher
;;;;;;

(define-rt-project mdagraph
  required-projects (mdakerne)
  root-directory #.rt-aida-directory
  system-directory #u"modana/"
  crunch-directory #u"modana/crunchdb/"
  directories (#u"modules/")
  project-file "aida.prj"
  )


;;;;;;
;;; HyperText
;;;;;;

(define-rt-project mdahyper
  required-projects (mdakerne mdagraph mdamlook mdatexte)
  root-directory #.rt-aida-directory
  system-directory #u"modana/"
  crunch-directory #u"modana/crunchdb/"
  directories (#u"modules/")
  project-file "aida.prj"
  )

...
...
...

;;;;;;
;;; Group-Projects
;;;;;;

(define-rt-group-project aida
  required-projects (x11 windows decw mdakerne mdatools))

...
\end{Longcode*}

On notera \`{a} la lecture des exemples ci-dessus que les projets
peuvent \^{e}tre d\'{e}pendants de mani\`{e}re arborescente\,: en d'autres termes, 
la clef {\tt required-projects} est
trait\'{e}e r\'{e}cursivement.

Au d\'{e}but de l'exemple sont d\'{e}finis des sous-projets tels que
\|mdakerne| et \|mdatools| qui requi\`{e}rent des projets de base
tels que \|lisp| ou \|x11| par exemple. 
A la fin de l'exemple, le v\'{e}ritable
projet \|aida| est d\'{e}fini comme un regroupement de ces sous-projets.
Les projets correspondant \`{a} des modules avanc\'{e}s tels que
\|mdagraph| et \|mdahyper| sont d\'{e}finis ensuite comme des
projets autonomes requ\'{e}rant certains des sous-projets d'\Aida.



%---------------------------------------------------------------------------
\Section {La commande d'analyse}
%---------------------------------------------------------------------------

Pour lancer l'{\em Analyseur de Modules}, il faut utiliser la
commande {\tt ll2lm}, habituellement rang\'{e}e dans le r\'{e}pertoire de la
machine, de \LeLisp . Si la commande n'est pas imm\'{e}diatement
op\'{e}rationnelle, on devra la refabriquer \`{a} l'aide du {\tt Makefile}
\LeLisp . Un exemple sur {\tt rs6000}\,:
\begin{Code*}
unix% cd /usr/ilog/lelisp/rs6000
unix% make ll2lm
\end{Code*}
On peut alors lancer l'analyseur de modules, avec par exemple, une des
options \|-defmodule| ou \|-update|\,: 
\begin{Code*}
unix% ll2lm -load myproject.prj -project myproject -defmodule mymod
 ...
unix% ll2lm -load myproject.prj -project myproject \
            -update /tmp/lm/mymod.lm
...
\end{Code*}

On peut aussi utiliser l'{\em Analyseur de Modules} en mode interactif\,:
\begin{Code*}
unix% ll2lm
; Welcome to Analyzer System
= interactive use
? (sh-analyze -load myproject.prj -project myproject -update mymod.lm)
 ...
\end{Code*}

{\it Se reporter au chapitre 6 pour en savoir plus sur ce mode d'activation
et sur d'autres techniques d'utilisation avanc\'{e}es.}

\medskip

La commande \|ll2lm| b\'{e}n\'{e}ficie d'un fichier d'initialisation :
\|ll2lm.ini|, normalement rang\'{e} dans le {\tt HOME} r\'{e}pertoire de
l'utilisateur. Ce fichier contiendra toutes les initialisations dont
l'utilisateur d\'{e}sire syst\'{e}matiquement profiter dans l'environnement
de l'analyseur.
\begin{Code*}
% cd
% cat ll2lm.ini
;;; To know what I am doing
(print "; You are using module analyzer")
;;; Default is english
(current-language 'french)
% ll2lm
; You are using module analyzer
; Welcome to Analyzer System
= interactive use
? t
t
\end{Code*}

\SSection{Les principales options d'analyse}

La commande d'analyse {\tt ll2lm} comporte un certain nombre d'options
exhaustivement \'{e}num\'{e}r\'{e}es dans le chapitre 5. 
Nous allons \'{e}tudier dans cette sections les options d'analyse les plus
courantes.
Un certain nombre d'entre elles, appel\'{e}es {\it
options pricipales} doivent n\'{e}cessairement apparaitre dans la
commande, selon le contexte d'emploi de cette derni\`{e}re. Par exemple,
si l'on utilise {\tt ll2lm} pour g\'{e}n\'{e}rer un {\tt Makefile}
il faut soit utiliser {\tt -init} soit utiliser {\tt -makefile}.
Voici les commandes principales\.:

\begin{itemize}
\item {les options de g\'{e}n\'{e}ration de {\bf {\tt Makefile}}\,:}
\begin{itemize}
\item {\tt -init} pour engendrer un {\bf Makefile initial}: ce {\tt Makefile}
permet de lancer en une seule commande, l'analyseur sur tous les
modules d'un projet,

\item {\tt -makefile} pour engendrer un {\bf Makefile de compilation} des
modules d\'{e}j\`{a} analys\'{e}s et construits,
\end{itemize}

\item {les options d'{\bf analyse}\,:}
\begin{itemize}
\item {\tt -defmodule mod} pour {\bf d\'{e}finir un module} de nom \|mod|
(sous la clef {\tt defmodule}),

\item {\tt -update mod.lm} pour {\bf mettre \`{a} jour} un fichier de
description modulaire \|mod.lm| d\'{e}j\`{a} existant,
\end{itemize}

\item {les options de gestion de la {\bf base des r\'{e}f\'{e}rences}\,:}
\begin{itemize}
\item {\tt -delete} pour {\bf effacer} un module d'une base de r\'{e}f\'{e}rence.

\item {\tt -build} pour engendrer le fichier de r\'{e}f\'{e}rences ({\bf
.ref}) d'un projet \`{a} partir de ses fichiers de description modulaire
({\tt .lm}),

\item {\tt -merge} pour {\bf concat\'{e}ner} deux fichiers de r\'{e}f\'{e}rences de
deux projets, en un seul fichier de r\'{e}f\'{e}rences,

\item {\tt -meta} pour engendrer un {\bf meta-module} \`{a} partir d'un
fichier de r\'{e}f\'{e}rences,
\end{itemize}
\end{itemize}

Pour toutes ces options principales (sauf \|-merge| pour laquelle on
pr\'{e}cise directement les deux projets concern\'{e}s), il faut
pr\'{e}ciser le projet de r\'{e}f\'{e}rence de l'analyse avec l'option \|-project| (ou
\|-p|) -- celui-ci devant \^{e}tre unique pour une analyse donn\'{e}e --. \\

Les options les plus utiles sont les suivantes\,:
\begin{itemize}

\item {\Large \|-project| {\em project}, \|-p| {\em project}}:
pour sp\'{e}cifier un projet.
Cette option est l'une des plus importantes
puisqu'elle doit presque toujours \^{e}tre sp\'{e}cifi\'{e}e, quelque soit
l'option principale. Il ne peut y avoir qu'un projet sp\'{e}cifi\'{e} \`{a} la
fois par analyse.
Voir \'{e}galement l'option \|-load| et
\|(declared-rt-projects)| 

\item {\Large \|-load| {\em file}}: permet de charger le fichier {\em file}
dans l'environnement d'analyse. En g\'{e}n\'{e}ral, il s'agit d'un fichier
de description de projet du type {\tt prjname.prj} et se place avant
l'option \|-project|. 
Cette option est cumulative.

\item {\Large \|-init|}: cette option principale permet, pour un
projet donn\'{e}, d'engendrer un fichier makefile d'analyse nomm\'{e} {\tt
projectname.mki}. 
C'est sans doute la {\bf premi\`{e}re option} \`{a} utiliser avec la
commande {\tt ll2lm}. 
L'usage de ce makefile {\tt projectname.mki} d\'{e}pend de l'\'{e}tat ``logiciel''
du projet.

Si le projet n'a jamais \'{e}t\'{e} analys\'{e} et qu'il s'agit d'une premi\`{e}re
mise en \oe uvre d'analyse sur les fichiers sources, il -- le fichier
makefile --  servira \`{a} fabriquer les  modules et les fichiers de
r\'{e}f\'{e}rences {\tt *.ref}, cette phase est 
appel\'{e}e phase de d\'{e}marrage. Elle n'est effectu\'{e}e normalement qu'une
seule fois pour chaque projet.

Si le projet est d\'{e}j\`{a} pass\'{e} par la phase de d\'{e}marrage et qu'il
faille le r\'{e}analyser pour prendre en compte les corrections
d\'{e}tect\'{e}es, il s'agit d'une mise \`{a} jour des modules et on parlera
alors de phase d'analyse incr\'{e}mentale. Il s'agit de l'usage principal de
l'analyseur de modules.

Le makefile {\tt projectname.mki} poss\`{e}de des entr\'{e}es sp\'{e}cifiques
pour ces deux phases\,:

\begin{Side}{\bf Phase de d\'{e}marrage}
Les entr\'{e}es pr\'{e}d\'{e}finies du makefile {\tt projectname.mki} \`{a}
utiliser dans cette phase sont {\tt init1} et {\tt init2}\,:
\end{Side}

\begin{itemize}
\item \|init1| \,: n'est \`{a} utiliser qu'une seule fois lors de la
toute premi\`{e}re analyse. Elle fabrique la base des r\'{e}f\'{e}rences du
projet ({\tt <project>.ref}) ainsi que l'ensemble des fichiers de
description de modules s'ils n'existent pas. La d\'{e}termination de
l'ensemble des modules d'un projet est d\'{e}taill\'{e}e plus avant.

\item \|init2| \,: est \`{a} utiliser une seule fois \'{e}galement apr\`{e}s
\|init1|. Elle sert \`{a} remettre \`{a} jour les fichiers de descriptions
modulaires {\tt *.lm} nouvellement cr\'{e}es. Ces derniers contiennent
obligatoirement  des informations incompl\`{e}tes \`{a} ce stade.
En effet de nombreux messages de l'analyseur pendant la phase {\tt
ini1} sont uniquement dus \`{a} l'absence de fichier des r\'{e}f\'{e}rences du
projet. 
\end{itemize}

\begin{Side}{\bf Phase d'analyse incr\'{e}mentale}
Il s'agit de l'usage habituel du fichier {\tt projectname.mki}. 
Le point d'entr\'{e}e par d\'{e}faut du makefile {\tt projectname.mki}
r\'{e}alise l'\'{e}quivalent de l'option \|-update| sur tous les modules du
projet. Apr\`{e}s une correction, dans les fichiers sources, relative \`{a}
chaque message important ({\tt ** ...}) issu d'une pr\'{e}c\'{e}dente
analyse, il suffit d'utiliser cette entr\'{e}e par d\'{e}faut que tous les modules
concern\'{e}s soient r\'{e}analys\'{e}s.  Cette entr\'{e}e est invoqu\'{e}e de la
mani\`{e}re suivante\,:
\BeginLL
         % make -f projectname.mki
\EndLL
\end{Side}

L'ensemble des modules du projet est d\'{e}duit \`{a} partir de la
d\'{e}finition du projet d'une des fa\c{c}ons suivantes\,:
\begin{enumerate}
\item si la clef \|modules| est pr\'{e}sente, elle sp\'{e}cifie
explicitement la liste des modules composant ce projet. Si sa valeur
est {\tt "all"}, nous sommes alors dans le cas 3;
\item si la clef \|modules-lists| est pr\'{e}sente, sa valeur est une
liste de fichiers dans lesquels on trouvera les listes des modules
constituant le projet, r\'{e}pertoire par r\'{e}pertoire. Cette liste est
\'{e}ventuellement amput\'{e}e des modules 
\'{e}num\'{e}r\'{e}s dans la clef  \|exclude-modules|. \\ 
Cette clef peut contenir la cha\^{\i}ne de caract\`{e}res {\tt "all"}\,: nous
sommes alors dans le cas 3;
\item Si une des 2 cl\'{e}s \|modules| ou \|modules-lists| contient la
cha\^{\i}ne de cract\`{e}res {\tt "all"}, la liste des modules est
constitu\'{e}e \`{a} partir de l'ensemble des 
fichiers source trouv\'{e}s dans les r\'{e}pertoires sp\'{e}cifi\'{e}s par la clef
\|directories|. Lors de la phase de d\'{e}marrage, si aucun fichier de
description modulaire n'est pr\'{e}sent, l'analyseur fabriquera un
fichier de description modulaire pour chaque fichier source {\tt
*.ll}.
\end{enumerate}
Si aucun de ces 3 cas n'est consid\'{e}r\'{e}, un message d'erreur sera
affich\'{e} :
\BeginLL
        ** -init : no file specified for project : project
\EndLL

Une derni\`{e}re entr\'{e}e \|clean| est disponible, elle efface tous les
fichiers de description modulaire du projet et la base de r\'{e}f\'{e}rences
du projet. 

Il est possible de pr\'{e}ciser des options d'analyse, module par module,
ou globalement\,: voir la clef {\tt analyzer-options} de {\tt
define-rt-project}. \\
Voir \'{e}galement l'option \|-dependency|.

\item {\Large \|-dependency| {\em level}, \|-dep| {\em level}}: pour
d\'{e}terminer le niveau de d\'{e}pendance du {\tt Makefile} engendr\'{e} (cf options
d'analyse \|-makefile| et \|-init|). \|level| peut prendre les valeurs
{\tt 0} (d\'{e}faut), {\tt 1}, {\tt 2} ({\tt 0}=d\'{e}pendance faible; {\tt
2}=d\'{e}pendance forte). Le d\'{e}tail est fourni chap\^{\i}tre 5.

\item {\Large \|-defmodule| {\em module-name}}: cette option
principale permet de 
sp\'{e}cifier le nom du module devant apparaitre sous la clef \|defmodule| du
module. L'utilisation de cette option signifie \`{a} l'analyseur de
fabriquer un nouveau fichier de description modulaire du module {\em
module-name}.
Par d\'{e}faut le nom de ce fichier est calcul\'{e} \`{a}
partir du nom du module (cf \|defmodule|) suffix\'{e} par l'extension {\tt
.lm}. Ce fichier est alors plac\'{e} dans le r\'{e}pertoire sp\'{e}cifi\'{e} par
la clef {\bf ll-module-directory} s'il existe, sinon par celui
sp\'{e}cifi\'{e} par {\bf ll-object-directory} s'il existe, ou sinon dans
le m\^{e}me r\'{e}pertoire que le premier fichier source trouv\'{e} dans le champ
\|files|. Il est toujours possible d'imposer un path et un nom de
fichier avec l'option \|-output|. \\
Voir \'{e}galement les clefs de {\tt define-rt-project}\ : 
les fichiers source devant appara\^{\i}tre sous le champ \|files| sont
calcul\'{e}s par d\'{e}faut \`{a} partir du nom du module\,: 
si la clef {\tt modules-files} est pr\'{e}sente dans 
la description du projet concern\'{e} (cf option \|-project|) et
concerne ce module, c'est elle qui fournira la liste exhaustive
des fichiers source. Dans le cas contraire, 
si la clef {\tt extensions-list} est
pr\'{e}sente, elle doit
contenir une liste d'extensions ({\tt ll, li}, ...) \`{a} adjoindre \`{a}
cette racine pour fabriquer les noms des fichiers source, sinon, si
cette clef n'est pas pr\'{e}sente, le
nom du fichier source sera {\em module-name}.{\tt ll}.

\item {\Large \|-update| {\em file.lm}, \|-u| {\em file.lm}}:
cette option principale est utilis\'{e}e pour demander la
mise \`{a} jour d'un module d\'{e}j\`{a} existant, dont on d\'{e}sire conserver
les informations d\'{e}j\`{a} existantes. 
Des commentaires seront
\'{e}ventuellement ajout\'{e}s dans le fichier {\tt file.lm}.
Contrairement \`{a} l'option \|defmodule|, ni les
importations, ni les exportations d\'{e}j\`{a} pr\'{e}sentes dans le module et
semblant inutiles ne seront
supprim\'{e}es. Les fonctions export\'{e}es sans \^{e}tre d\'{e}finies dans
les sources de ce module engendrent le warning {\tt W.105}.

\item {\Large \|-verbose| {\em level}, \|-v| {\em level}}: pour
d\'{e}terminer le niveau de 
messages de l'analyse. \|level| peut prendre les valeurs 0, 1, 2\,: 
\begin{itemize}
\item 0 (d\'{e}faut)\ :
niveau minimun de messages\,: seuls les messages importants
n\'{e}cessitant une intervention, sont imprim\'{e}s \`{a} l'\'{e}cran,
\item 1 \ :
l'analyseur d\'{e}taille l'ensemble des op\'{e}rations effectu\'{e}es,
\item 2 \ :
l'analyseur \'{e}met en plus un diagnostic de son analyse en commentant
ses choix.
\end{itemize}
Le niveau de messages requis lors de la fabrication d'un {\tt Makefile}
donne le niveau de messages durant l'utilisation de ce {\tt Makefile}.
Cette option se combine avec toutes les autres options.

\end{itemize}

%---------------------------------------------------------------------------
\Section{D\'{e}roulement d'une analyse}
%---------------------------------------------------------------------------

Une fois que le projet est cr\'{e}\'{e}, que les r\'{e}pertoires d'analyse sont
d\'{e}finis, etc, on peut lancer l'analyse sur chacun des modules du
projet.
Nous verrons en d\'{e}tail comment utiliser les commandes d'analyse dans
le paragraphe suivant. Cette section d\'{e}crit le d\'{e}tail d'une analyse.
Une analyse se d\'{e}roule en quatre temps\,:

\begin {enumerate}

\item Chargement des informations li\'{e}es au projet,

\item Analyse proprement dite du module,

\item Affichage d'un diagnostic concernant les imports et les exports,

\item \'{E}criture des r\'{e}sultats dans le module et dans la base de
r\'{e}f\'{e}rence du projet concern\'{e}.
\end {enumerate}

Les 4 paragraphes suivants d\'{e}crivent ces 4 items.

%---------------------------------------------------------------------------
\SSection {Contexte d'analyse}
%---------------------------------------------------------------------------
Le {\it contexte d'analyse} est \'{e}labor\'{e} \`{a} partir du {\bf projet}.
Pour activer un projet, on doit le sp\'{e}cifier dans la commande
d'analyse avec l'option \|-project|.\\
La premi\`{e}re chose que fait l'{\em Analyseur de Modules} est de mettre
\`{a} jour son environnement d'analyse en chargeant et activant les
d\'{e}finitions de 
projets requises pour cette analyse (cf \|required-projects|).
La variable \|#:system:path| en particulier, est mise \`{a} jour avec le
contenu des clefs \|directories| des projets requis, et \'{e}ventuellement
le contenu des clefs \|ll-module-directory|. Cette valeur est
cruciale, puisque toutes les recherches de modules qui auront lieu
durant l'analyse, se feront dans cet environnement. \\
Voici un exemple de premi\`{e}re phase d'analyse sur un projet {\tt
test}, lequel requiert le projet {\tt lisp}: \\

\begin{Longcode*}
=====
===== STEP 1 : loading context of project : test
=====
.. reading file(s) : #p"/usr/ilog/lelisp/modana/lisp.ref"
===== path environment for this analyze :
   #p""
   #p"/usr/ilog/lelisp/test/lm/"
   #p"/usr/ilog/lelisp/test/ll/"
   #p"/usr/ilog/lelisp/sun4/"
   #p"/usr/ilog/lelisp/llib/"
   #p"/usr/ilog/lelisp/llobj/"
   #p"/usr/ilog/lelisp/llmod/"
\end{Longcode*}

\begin{Side}{\bf Remarque}
Les exemples concernant les diff\'{e}rentes
phases  d'analyse sont tous effectu\'{e}s en mode \|-verbose 2|.
\end{Side}

\begin{Side}{\bf Rappel}
Afin de faciliter l'analyse des modules, des projets (ou
\|define-rt-project|) ont \'{e}t\'{e} pr\'{e}d\'{e}finis pour chaque produit \Ilog.
On trouvera de telles d\'{e}finitions pour \LeLisp, \Aida\ ou
\Smeci\ mais aussi
les modules avanc\'{e}s d'\Aida\ tels que le {\tt grapheur} ou l'{\tt
hypertexte}. 
\end{Side}

%---------------------------------------------------------------------------
\SSection {Analyse d'un module}
%---------------------------------------------------------------------------

L'analyse proprement dite est la deuxi\`{e}me phase r\'{e}alis\'{e}e\,: les
fichiers source du module analys\'{e} sont d'abord lus, puis le code ainsi
lu est analys\'{e} dans le d\'{e}tail, forme par forme. Il est bon de noter
que les algorithmes utilis\'{e}s pendant cette analyse sont les m\^{e}mes
que ceux du compilateur {\tt complice}. \\
Un exemple de phase d'analyse sur le module {\tt product} de la
librairie standard \LeLisp\,:

\begin{Longcode*}
=====
===== STEP 2 : browsing files of module : product
=====          involved files are : (product.ll)
=====
.. reading file(s) : (product.ll)
.. unknown function make-hash-table-eq - it's exported by module : (hash)
.. evaluating CPENV field of module : setf
.. evaluating CPENV field of module : cpmac
.. evaluating CPENV field of module : hash
.. scanning functions : ...
.. unknown function puthash - it's exported by module : (hash)
.. unknown function gethash - it's exported by module : (hash)
.. unknown function #:hash-table:vect - it's exported by module : (hash)

\end{Longcode*}

%---------------------------------------------------------------------------
\SSection {Diagnostics}
%---------------------------------------------------------------------------

L'{\em Analyseur de Modules}, apr\`{e}s avoir analys\'{e} un module, et s'il
est en mode \|verbose| maximum, \'{e}met un certain nombre de renseignements
sur les r\'{e}sultats de son analyse\,: c'est la troisi\`{e}me phase d'une
analyse compl\`{e}te. Ces informations portent en
particulier sur les raisons pour lesquelles on importe des modules, et
les raisons pour lesquelles on exporte (ou pourquoi on n'exporte pas)
telle ou telle fonction.\\
Il est fortement recommand\'{e} de lire les fichiers descripteurs de
modules ({\tt .lm}) r\'{e}sultant de l'analyse, pour comprendre le travail
de l'analyseur. Les listes inscrites dans le {\tt .lm} sont
comment\'{e}es \`{a} cet effet.\\
Reprenons notre exemple du module {\tt product} de la librairie
\LeLisp\ :

\begin{Longcode*}
=====
===== STEP 3 : diagnostic
=====

===== Concerning IMPORTS :
- Modules that are required for compilation :
- You have to import "hash" because of :
 make-hash-table-eq puthash gethash #:hash-table:vect .

===== Concerning EXPORTS :
- The following functions will be unused unless exported :
     product-print
     product-all-names
     set-product-comment
     product-comment
     set-product-subversion
     product-subversion
     set-product-version
     product-version
     set-product-date
     product-date
     set-product-id
     product-id
     product-build-info
- The following exports are not necessary :
     #:product:gethash

\end{Longcode*}

%---------------------------------------------------------------------------
\SSSection {Importation des modules}
%---------------------------------------------------------------------------

Si l'{\em Analyseur de Modules} a d\'{e}tect\'{e} des fonctions qui ne sont pas d\'{e}finies
\`{a} l'int\'{e}rieur du module analys\'{e}, il en g\'{e}n\`{e}re la liste.

Si par exemple le module contient une utilisation des fonctions {\tt
unknown-function-1} et {\tt motif-pushbutton} et de l'abr\'{e}viation
{\tt myabbrev} qui ne sont d\'{e}finies ni par
lui-m\^{e}me, ni par \Aida\ ou \LeLisp, l'{\em Analyseur de Modules} affichera\,:

\begin{Longcode*}
===== Concerning IMPORTS :
--
-- Each of the following is "undefined function"
--      unknown-function-1 
--      motif-pushbutton
--
-- Each of the following is "not an abbreviation"
--      a-bar1
--
-- Modules defining these entities have to be analyzed before module: foo
-- If these entities are defined in ILOG products, please specify
-- the correct context(s) for analysis.

\end{Longcode*}

Cela signifie que l'{\em Analyseur de Modules} n'a pas trouv\'{e} les
d\'{e}finitions de ces fonctions ni celles de l'abr\'{e}viation, et ceci dans
aucun des modules accessibles.
Les trois causes les 
plus plausibles sont:

\begin {Itemize}

\item Ces fonctions sont dans les produits \Ilog \ mais le projet
qui les d\'{e}finit n'est pas charg\'{e} (c'est le cas de la
fonction \|motif-pushbutton|, pour lequel on doit sp\'{e}cifier le
projet \|motif|). \\
{\it Correction}\ : ajouter le (ou les) projet(s) dans la clef {\tt
required-projects} de 
la d\'{e}finition de ce projet (cf. {\tt define-rt-project}).
On pourra utiliser la fonction \|func-from| (voir plus loin) pour
tester l'appartenance de ces fonctions \`{a} un module d'un produit
\Ilog.

\item Ces deux fonctions existent r\'{e}ellement et elles ne sont pas
d\'{e}finies dans des modules d'\Aida\ ou \LeLisp\ mais dans des
sous-modules non encore analys\'{e}s du module en cours d'analyse. \\
{\it Corrections possibles}\ : analyser les sous-modules en question avant
de re-analyser ce module, utiliser l'option \|-import| 
pour imposer l'importation de ces modules, ou \'{e}diter le
module en question pour imposer ces sous-modules dans le champ {\tt import}.

\item Les noms des fonctions en question ont \'{e}t\'{e} mal orthographi\'{e}s.\\
{\it Correction}\ : corriger le source.

\end {Itemize}

Si notre module utilise la fonction \LeLisp\ {\tt new} export\'{e}e par
le module {\tt defstruct} mais que ce module {\tt defstruct} ne figure
pas dans les imports de notre module, l'{\em Analyseur de Modules} affichera\,:

\begin{Longcode*}
- Modules that are required for compilation:
- You have to import "defstruct" because of:
 new .
\end{Longcode*}

S'il emploie l'abr\'{e}viation \|{scroller}| et les fonctions {\tt
verticalscroller} et {\tt horizontalscroller} sans avoir import\'{e} le
module {\tt scroller} qui la d\'{e}finit, l'{\em Analyseur de Modules}
affichera\,: 

\begin{Longcode*}
- You have to import "scroller" because of:
 scroller verticalscroller horizontalscroller .
\end{Longcode*}


Si maintenant, et lors d'une mise \`{a} jour uniquement (cf option
\|-update|), un module ({\tt buttonbox} par exemple) 
est d\'{e}j\`{a} pr\'{e}sent dans le
champ \|import| ou impos\'{e} via l'option d'analyse \|-import|, mais
que l'{\em Analyseur de Modules} n'a trouv\'{e} 
aucune utilisation de fonctions 
export\'{e}es par ce module, il affiche le message\,:

\begin{Longcode*}
- these modules do not seem useful :
 buttonbox .
\end{Longcode*}

Il est \`{a} noter que, si nous sommes en phase de mise \`{a} jour
(\|-update|), le module reste dans la liste des importations du 
module. Une intervention manuelle peut \'{e}ventuellemnet s'av\'{e}rer
n\'{e}cessaire. En effet certains cas d'appels dynamiques par exemple,
peuvent ne pas \^{e}tre d\'{e}tect\'{e}s par l'{\em Analyseur de modules},
m\^{e}me avec l'option d'analyse \|-dynamic|. Par contre, en 
phase de fabrication d'un nouveau module (option d'analyse
\|-defmodule|), le module {\tt 
buttonbox} n'apparaitrait pas dans la liste des importations du module
analys\'{e}. 

%---------------------------------------------------------------------------
\SSSection {Exportation des fonctions}
%---------------------------------------------------------------------------

L'{\em Analyseur de Modules} consid\`{e}re comme n\'{e}cessaires 
les seules exportations concernant les 
fonctions d\'{e}finies dans le module analys\'{e} et qui n'y sont pas
utilis\'{e}es.

Il signale donc celles qu'il juge non n\'{e}cessaires car utilis\'{e}es en
interne\,:

\begin{Longcode*}
- The following exports are not necessary :
 client-mode
 formatted-map-rats
 formatted-rat-summary
 rat
 #:rat:view-rat
 {application}:abs-x-y
\end{Longcode*}

Avoir d\'{e}clar\'{e} ces exports n'est pas une erreur, s'il s'agit bien de
fonctions que l'on souhaite exporter.

Par contre, si le programmeur a indiqu\'{e} dans la rubrique {\tt export}
(ou via l'option \|-export|)
des fonctions qui ne sont pas d\'{e}finies par le module (par exemple,
les fonctions {\tt my-function-1} et {\tt my-function-2}), l'{\it Analyseur
de Modules} affiche\,:

\begin{Longcode*}
- The following exports are not defined :
 my-function-1
 my-function-2
\end{Longcode*}

Un warning {\tt W.105} aura \'{e}t\'{e} \'{e}mis pour ces 2 fonctions, lors de
l'analyse du module. 

Si l'analyseur d\'{e}couvre des fonctions qui sont d\'{e}finies dans le
module et non utilis\'{e}es, il suppose qu'elles doivent \^{e}tre
export\'{e}es.  Par exemple, si on a d\'{e}fini {\tt f} et {\tt g} sans les
utiliser en interne, il affiche:

\begin{Longcode*}
- The following functions will be unused unless exported:
 f
 g
\end{Longcode*}

Enfin, il est parfois n\'{e}cessaire d'exporter des fonctions d\'{e}j\`{a}
utilis\'{e}es en interne, soit pour l'utilisateur, soit pour d'autres
modules. Dans ce cas, les fonctions internes devront \^{e}tre pr\'{e}cis\'{e}es
au moyen de l'option d'analyse \|-export|, ou bien \^{e}tre d\'{e}j\`{a}
pr\'{e}sentes dans le champs \|export| du module en cours d'analyse, s'il
s'agit d'un \|update|. Par exemple, si la fonction
interne {\tt formatted-rat-summary} est forc\'{e}e en exportation avec
l'option d'analyse \|-export|, on aura le message:

\begin{Longcode*}
- The following exports seem necessary for other modules :
     formatted-rat-summary
\end{Longcode*}

\begin{Side}{\bf Remarque}
le comportement en question varie selon que nous sommes en
mode cr\'{e}ation d'un nouveau module 
(\|-defmodule|) ou mise \`{a} jour d'un module existant (\|-update|).
Dans le premier cas, il est n\'{e}cessaire d'utiliser l'option \|-export|
pour imposer une exportation (en effet le module n'existe pas
encore!),
dans le second cas, il est possible d'imposer l'exportation d'un
module soit avec l'option \|-export| soit en \'{e}ditant manuellement le
fichier de description du module d\'{e}j\`{a} existant.
\end{Side}

L'{\em Analyseur de Modules} ne reconna\^{\i}t pas toujours les fonctions
appel\'{e}es par {\tt 
apply}, {\tt funcall}, {\tt mapcar}, etc.. car leur nom peut \^{e}tre
dissimul\'{e} dans des variables ou occult\'{e} par d'autres informations
sans rapport. Seul le cas o\`{u} le nom de la fonction appel\'{e}e apparait
{\em quot\'{e}e} est reconnaissable automatiquement par l'{\em Analyseur de
Modules} \`{a} condition d'utiliser l'option d'analyse \|-dynamic|, et le
d\'{e}finisseur {\tt defdynamic} (cf. {\tt defdynamic}).

%---------------------------------------------------------------------------
\SSSection {Restrictions}
%---------------------------------------------------------------------------

Se reporter \`{a} l'annexe B pour le r\'{e}sum\'{e} des restrictions d'analyse.

%---------------------------------------------------------------------------
\SSection {Mise \`{a} jour du fichier descripteur de module}
%---------------------------------------------------------------------------

La quatri\`{e}me et derni\`{e}re phase d'une analyse de module compl\`{e}te est
la mise \`{a} jour des fichiers concern\'{e}s, \`{a} savoir\,: le fichier de
description modulaire lui-m\^{e}me, et le fichier des r\'{e}f\'{e}rences.\\
Finissons notre exemple sur le module {\tt product}:

\begin{Longcode*}
=====
===== STEP 4 : updating module description : #p"/usr/ilog/lelisp/test/lm/product.lm"
=====
.. Previous file #p"/usr/ilog/lelisp/test/lm/product.lm" saved in :
#p"/usr/ilog/lelisp/test/lm/product.lm~"
.. updating module description file : #p"/usr/ilog/lelisp/test/lm/product.lm"

=====
===== STEP 4bis : updating reference file : #p"/usr/ilog/lelisp/test/test.ref"
=====
.. reading file(s) : #p"/usr/ilog/lelisp/test/test.ref"
.. Previous file #p"/usr/ilog/lelisp/test/test.ref" saved in :
#p"/usr/ilog/lelisp/test/test.ref~"
.. updating reference file : #p"/usr/ilog/lelisp/test/test.ref"
\end{Longcode*}

On devra prendre soin d'utiliser l'option \|-nowrite|, en niveau
\|-verbose 2|, si on d\'{e}sire
seulement ``voir{''} les diagnostics de l'{\em Analyseur de Modules}
sans modifier aucun fichier.

Une sauvegarde de l'ancienne version de ce
fichier est effectu\'{e}e par s\'{e}curit\'{e}.  Par exemple: si le descripteur
s'appelait {\tt mymod.lm}, la mise \`{a} jour
produit un fichier {\tt mymod.lm} (sur Unix) contenant
l'ancienne d\'{e}finition, et recr\'{e}e enti\`{e}rement le fichier {\tt
mymod.lm}.


