# Introduction

Ce didacticiel est destiné aux utilisateurs maîtrisant la programmation en C ou C++, ainsi que l'architecture de la Simple Virtual Machine.

Dans ce didacticiel, vous allez apprendre à décorer une extension en vue de sa publication.

Le temps de lecture de ce didacticiel est estimé à 20 minutes.

# Mise en place

Pour commencer, créez le canevas de l'extension dans le fichier publication.svm_plugin en utilisant ce code :

    PLUGIN publish
    lang: "C++"

    synopsis: "My own integer division."

    description:
    %{
    This plugin is a full duplicate of the :int.div instruction.
    .P
    No more, no less.
    %}

    example: "Simple example"
    %{
    .nf
    #!/usr/bin/env svm
    LOG
    PLUGIN "svmcom.so"
    MACHINE PLUGIN "===PLUGINMACHINELIB==="
    PROCESS "example"
    	CODE "main" INLINE
    		:memory INT/i
    		:publish.instruction 12 3 -> &i
    		:com.message @&i
    	END
    END
    .fi
    %}

    test: "Simple_test"
    %{
    PLUGIN "svmint.so"
    PROCESS "test"
    	CODE "main" INLINE
    		:memory INT/i, BLN/b
    		:publish.instruction 12 3 -> &i
    		:int.cmp @&i = 4 -> &b
    		:shutdown 1 :unless @&b TRUE
    	END
    END
    %}

    test: "Error_test"
    %{
    PROCESS "test"
    	CODE "main" INLINE
    		:interruption NUMERIC error
    		:memory INT/i
    		:publish.instruction 12 0 -> &i
    		:shutdown 1
    	:label error
    	END
    END
    %}

    DEFINE

    INSTRUCTION publish.instruction INT INT -> INT
    %{
    	auto l = ARGV_VALUE(0,integer);
    	auto r = ARGV_VALUE(1,integer);
    	if(r==0)
    	{
    		ERROR_INTERNAL(NUMERIC,"Division by zero.");
    	}
    	return NEW_VALUE(integer,l/r);
    %}
    help:
    %{
    A safe division between integers.
    .P
    This instruction raises a NUMERIC interruption when the divisor is 0.
    %}

# Préparation

## Identification

La première étape consiste à identifier l'extension en lui donnant un titre, une version et sa date de création.

Modifiez le code de l'extension :

    PLUGIN publish
    lang: "C++"
    title: "Another safe division"
    version: "1.0.0"
    date: "2023-01-01"

    synopsis: "My own integer division."

    description:
    %{
    This plugin is a full duplicate of the :int.div instruction.
    .P
    No more, no less.
    %}

    example: "Simple example"
    %{
    .nf
    #!/usr/bin/env svm
    LOG
    PLUGIN "svmcom.so"
    MACHINE PLUGIN "===PLUGINMACHINELIB==="
    PROCESS "example"
    	CODE "main" INLINE
    		:memory INT/i
    		:publish.instruction 12 3 -> &i
    		:com.message @&i
    	END
    END
    .fi
    %}

    test: "Simple_test"
    %{
    PLUGIN "svmint.so"
    PROCESS "test"
    	CODE "main" INLINE
    		:memory INT/i, BLN/b
    		:publish.instruction 12 3 -> &i
    		:int.cmp @&i = 4 -> &b
    		:shutdown 1 :unless @&b TRUE
    	END
    END
    %}

    test: "Error_test"
    %{
    PROCESS "test"
    	CODE "main" INLINE
    		:interruption NUMERIC error
    		:memory INT/i
    		:publish.instruction 12 0 -> &i
    		:shutdown 1
    	:label error
    	END
    END
    %}

    DEFINE

    INSTRUCTION publish.instruction INT INT -> INT
    %{
    	auto l = ARGV_VALUE(0,integer);
    	auto r = ARGV_VALUE(1,integer);
    	if(r==0)
    	{
    		ERROR_INTERNAL(NUMERIC,"Division by zero.");
    	}
    	return NEW_VALUE(integer,l/r);
    %}
    help:
    %{
    A safe division between integers.
    .P
    This instruction raises a NUMERIC interruption when the divisor is 0.
    %}

La directive `title` permet de donner un titre à l'extension. Ce titre est utilisé comme titre dans la page de manuel, et se retrouve également dans tous les fichiers où la licence apparaît.

La directive `version` permet de donner le numéro de version de l'extension dont le fichier est la source.

La directive `date` permet de donner la date de création de l'extension. Le format recommandé est AAAA-MM-JJ.

## Gestion

Après l'identification de l'extension elle-même, vient le tour de celle de l'auteur, et du mainteneur. Il est également possible d'inclure la liste des changements réalisés sur l'extension pour assurer le suivi de son évolution.

Modifiez le code de l'extension :

    PLUGIN publish
    lang: "C++"
    title: "Another safe division"
    version: "1.0.0"
    date: "2023-01-01"
    author: "Ann Nonymous"
    maintainer: "Ann Nonymous <ann.nonymous@example.com>"
    changelog:
    %{
    2023-01-01: Initial release.
    2023-01-02: Adding error test.
    %}

    synopsis: "My own integer division."

    description:
    %{
    This plugin is a full duplicate of the :int.div instruction.
    .P
    No more, no less.
    %}

    example: "Simple example"
    %{
    .nf
    #!/usr/bin/env svm
    LOG
    PLUGIN "svmcom.so"
    MACHINE PLUGIN "===PLUGINMACHINELIB==="
    PROCESS "example"
    	CODE "main" INLINE
    		:memory INT/i
    		:publish.instruction 12 3 -> &i
    		:com.message @&i
    	END
    END
    .fi
    %}

    test: "Simple_test"
    %{
    PLUGIN "svmint.so"
    PROCESS "test"
    	CODE "main" INLINE
    		:memory INT/i, BLN/b
    		:publish.instruction 12 3 -> &i
    		:int.cmp @&i = 4 -> &b
    		:shutdown 1 :unless @&b TRUE
    	END
    END
    %}

    test: "Error_test"
    %{
    PROCESS "test"
    	CODE "main" INLINE
    		:interruption NUMERIC error
    		:memory INT/i
    		:publish.instruction 12 0 -> &i
    		:shutdown 1
    	:label error
    	END
    END
    %}

    DEFINE

    INSTRUCTION publish.instruction INT INT -> INT
    %{
    	auto l = ARGV_VALUE(0,integer);
    	auto r = ARGV_VALUE(1,integer);
    	if(r==0)
    	{
    		ERROR_INTERNAL(NUMERIC,"Division by zero.");
    	}
    	return NEW_VALUE(integer,l/r);
    %}
    help:
    %{
    A safe division between integers.
    .P
    This instruction raises a NUMERIC interruption when the divisor is 0.
    %}

La directive `author` doit idéalement contenir le ou les noms des auteurs de l'extension. Il n'y a pas de format recommandé pour cette directive.

La directive `maintainer` doit idéalement contenir le ou les noms des mainteneurs de l'extension, avec leur adresse de courriel entre < et >.

Ces informations sont répliquées dans la page d'aide et sur les portions de licence ajoutées dans tous les fichiers.

La directive `changelog` est d'un format libre, et se contente de copier le contenu du bloc dans un fichier spécial dans le répertoire de l'extension.

## Droits d'utilisation

Enfin, il est important d'indiquer les droits d'utilisation associés à l'extension.

Modifiez le code de l'extension :

    PLUGIN publish
    lang: "C++"
    title: "Another safe division"
    version: "1.0.0"
    date: "2023-01-01"
    author: "Ann Nonymous"
    maintainer: "Ann Nonymous <ann.nonymous@example.com>"
    changelog:
    %{
    2023-01-01: Initial release.
    2023-01-02: Adding error test.
    %}
    license:
    %{
    This is a plugin usable only by SVM trainees.

    All other usages are prohibited. Please use :int.div instruction instead.
    %}
    usage:
    %{
    Plugin only for SVM training.
    %}

    synopsis: "My own integer division."

    description:
    %{
    This plugin is a full duplicate of the :int.div instruction.
    .P
    No more, no less.
    %}

    example: "Simple example"
    %{
    .nf
    #!/usr/bin/env svm
    LOG
    PLUGIN "svmcom.so"
    MACHINE PLUGIN "===PLUGINMACHINELIB==="
    PROCESS "example"
    	CODE "main" INLINE
    		:memory INT/i
    		:publish.instruction 12 3 -> &i
    		:com.message @&i
    	END
    END
    .fi
    %}

    test: "Simple_test"
    %{
    PLUGIN "svmint.so"
    PROCESS "test"
    	CODE "main" INLINE
    		:memory INT/i, BLN/b
    		:publish.instruction 12 3 -> &i
    		:int.cmp @&i = 4 -> &b
    		:shutdown 1 :unless @&b TRUE
    	END
    END
    %}

    test: "Error_test"
    %{
    PROCESS "test"
    	CODE "main" INLINE
    		:interruption NUMERIC error
    		:memory INT/i
    		:publish.instruction 12 0 -> &i
    		:shutdown 1
    	:label error
    	END
    END
    %}

    DEFINE

    INSTRUCTION publish.instruction INT INT -> INT
    %{
    	auto l = ARGV_VALUE(0,integer);
    	auto r = ARGV_VALUE(1,integer);
    	if(r==0)
    	{
    		ERROR_INTERNAL(NUMERIC,"Division by zero.");
    	}
    	return NEW_VALUE(integer,l/r);
    %}
    help:
    %{
    A safe division between integers.
    .P
    This instruction raises a NUMERIC interruption when the divisor is 0.
    %}

La directive `license` est d'un format libre, et se contente de copier le contenu du bloc dans un fichier spécial dans le répertoire de l'extension.

La directive `usage` est aussi d'un format libre et doit synthétiser en quelques lignes la licence d'utilisation. Le contenu de cette directive est repliqué en en-tête de tous les fichiers qui peuvent être commentés.

- L'identification de l'extension se fait avec les directives `title`, `version` et `date`.
- La gestion de l'extension se fait avec les directives `author`, `maintainer` et `changelog`.
- L'expression des droits d'utilisation de l'extension se fait avec les directives `license` et `usage`. Lorsque ces directives ne sont pas présentes, l'extension est automatiquement placée en GPLv3.
- Toutes ces directives ne peuvent être présentes qu'une fois, dans la section générale de l'extension.

# Publication

L'extension est maintenant prête à être publiée ! Il reste cependant deux choix importants à faire.

## Libre ou propriétaire

Le premier choix concerne la licence d'utilisation de l'extension :

- La première possibilité est d'en faire un logiciel libre. Les droits d'auteur sont garantis par la licence, et l'extension peut être librement utilisée, modifiée et redistribuée. Selon la licence, des versions modifiées de l'extension peuvent être utilisé dans un contexte commercial.
- La seconde possibilité est d'en faire un logiciel propriétaire. Dans ce cas, le code source n'est pas publié, et seul le .so et la page de manuel doivent être publiées. Il existe toutefois une contrainte importante à respecter par tous les fournisseurs d'extensions propriétaires : une version compatible avec la dernière version de la machine vituelle doit toujours être disponible.

## Officiel, communautaire ou indépendant

Le second choix concerne le média de publication de l'extension :

- La première possibilité est de publier l'extension de manière indépendante. Cette méthode de publication a l'avantage d'être la moins contraignante pour un auteur d'extension. Cette méthode est tout à fait adaptée aux extensions qui sont spécifiques à une application.
- La seconde possibilité est de publier l'extension dans l'espace communautaire de la machine virtuelle. Cette méthode impose une licence de type logiciel libre sur l'extension, mais permet de prendre en charge automatiquement la regénération et recompilation en cas de nouvelle version de la machine virtuelle.
- La troisième possibilité est de publier l'extension dans le projet de la machine virtuelle. Cette méthode impose une licence de type logiciel libre, une intention louable dans l'utilisation de l'extension, et une implémentation irréprochable de la gestion de la mémoire. Cette méthode est tout à fait adaptée aux extensions ultra-génériques.

- Il est temps de publier l'extension, elle est maintenant terminée.
- Il reste à choisir la licence d'utilisation de l'extension avec soin, libre ou propriétaire.
- Il reste également à choisir où publier l'extension, pour une prise en charge plus ou moins complète et des facilités de publication.

# Conclusion

Vous venez de voir comment préparer une extension pour la publier.

Cette dernière étape, bien que peu technique, est pourtant cruxiale pour la pérennité d'une extension. Elle peut largement influencer la popularité d'une extension.

Et au-delà de cette étape, il est temps pour vous d'imaginer vos propres extensions et de les implémenter !