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 à ajouter de l'aide aux extensions.

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

Mise en place

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

PLUGIN help

DEFINE

OPTION help.prefix -p STR

TYPE help.type
%{
	std::string _s;
%}
delete default: %{}

INSTRUCTION help.new STR -> help.type
%{
	auto rs = ARGV_VALUE(0,string);
	auto s = RAW_STRING(rs);
	SVM_Value_String p = ::svm_plugin_get_option(svm,CONST_PEP(help,prefix));
	if(not ::svm_value_state_is_null(svm,p))
	{
		auto rp = ::svm_value_string_get(svm,p);
		s = RAW_STRING(rp)+s;
	}
	return NEW_PLUGIN(help,type,new type_type { s });
%}

Aide générale

Pour commencer, générez et compilez cette extension. Puis dans le terminal, lancez la commande depuis le répertoire où a été générée l'extension :

man ./doc/svm_plugin_help.man

Le générateur d'extension a généré une page d'aide, certes incomplète, pour aider les développeurs d'applications Simple Virtual Machine à utiliser l'extension.

La première chose à faire pour compléter l'aide est de fournir une idée générale de ce que fait l'extension.

Modifiez le code de l'extension :

PLUGIN help

synopsis:
%{
This plugin handles a useless type.
%}

description:
%{
This plugin allows an application to create a type containing a string with an optional prefix.
.P
This prefix is configured by an option at application level.
%}

DEFINE

OPTION help.prefix -p STR

TYPE help.type
%{
	std::string _s;
%}
delete default: %{}

INSTRUCTION help.new STR -> help.type
%{
	auto rs = ARGV_VALUE(0,string);
	auto s = RAW_STRING(rs);
	SVM_Value_String p = ::svm_plugin_get_option(svm,CONST_PEP(help,prefix));
	if(not ::svm_value_state_is_null(svm,p))
	{
		auto rp = ::svm_value_string_get(svm,p);
		s = RAW_STRING(rp)+s;
	}
	return NEW_PLUGIN(help,type,new type_type { s });
%}

Générez à nouveau l'extension et rouvrez la page de manuel. Cette fois, des sections synopsis et description indiquent ce que réalise l'extension :

  1. La section synopsis est en général une ligne d'accroche qui permet d'un coup d'œil de savoir à quoi l'extension sert.
  2. La section description est quant à elle plus vaste, et précise comment fonctionne l'extension dans son ensemble.

Notez que le texte contenu dans les blocs d'aide sont des extraits de page de manuel, écrits en groff. Référez vous à la documentation de cet outil pour de plus amples détails sur sa syntaxe.

Exemples

Parfois, quelques exemples d'utilisation d'une extension facilitent beaucoup la compréhension des utilisateurs.

Modifiez le code de l'extension :

PLUGIN help

synopsis:
%{
This plugin handles a useless type.
%}

description:
%{
This plugin allows an application to create a type containing a string with an optional prefix.
.P
This prefix is configured by an option at application level.
%}

example: "Basic usage"
%{
.nf
#!/usr/bin/env svm
LOG
MACHINE PLUGIN "===PLUGINMACHINELIB==="
PROCESS "example"
	CODE "main" INLINE
		:memory help.type/t
		:help.new "value" -> &t
	END
END
.fi
%}

example: "With prefix"
%{
.nf
#!/usr/bin/env svm
LOG
MACHINE PLUGIN "===PLUGINMACHINELIB===" -p "prefix-"
PROCESS "example"
	CODE "main" INLINE
		:memory help.type/t
		:help.new "value" -> &t
	END
END
.fi
%}

DEFINE

OPTION help.prefix -p STR

TYPE help.type
%{
	std::string _s;
%}
delete default: %{}

INSTRUCTION help.new STR -> help.type
%{
	auto rs = ARGV_VALUE(0,string);
	auto s = RAW_STRING(rs);
	SVM_Value_String p = ::svm_plugin_get_option(svm,CONST_PEP(help,prefix));
	if(not ::svm_value_state_is_null(svm,p))
	{
		auto rp = ::svm_value_string_get(svm,p);
		s = RAW_STRING(rp)+s;
	}
	return NEW_PLUGIN(help,type,new type_type { s });
%}

Générez à nouveau l'extension et rouvrez la page de manuel. Cette fois, à la fin de la page apparaissent des exemples de code.

Un fichier source d'extension peut contenir plusieurs exemples, qui ont chacun :

  1. une chaine entre double-quotes servant de titre à l'exemple,
  2. un bloc en groff (notez les balises .nf et .fi pour délimiter un bloc non formatté) qui contient l'exemple. La chaine ===PLUGINMACHINELIB=== sera ici remplacée par le chemin vers l'extension lorque celle-ci sera installée avec autotools.

Objets

Dans les pages d'aide générées, les objets définis par l'extension sont listés avec un texte générique indiquant que l'aide n'est pas disponible pour ces objets.

Modifiez le code de l'extension :

PLUGIN help

synopsis:
%{
This plugin handles a useless type.
%}

description:
%{
This plugin allows an application to create a type containing a string with an optional prefix.
.P
This prefix is configured by an option at application level.
%}

example: "Basic usage"
%{
.nf
#!/usr/bin/env svm
LOG
MACHINE PLUGIN "===PLUGINMACHINELIB==="
PROCESS "example"
	CODE "main" INLINE
		:memory help.type/t
		:help.new "value" -> &t
	END
END
.fi
%}

example: "With prefix"
%{
.nf
#!/usr/bin/env svm
LOG
MACHINE PLUGIN "===PLUGINMACHINELIB===" -p "prefix-"
PROCESS "example"
	CODE "main" INLINE
		:memory help.type/t
		:help.new "value" -> &t
	END
END
.fi
%}

DEFINE

OPTION help.prefix -p STR
help: "This option specifies the prefix to add to all values of the useless type."

TYPE help.type
%{
	std::string _s;
%}
delete default: %{}
help:
%{
This type is the useless type.
.P
It contains only a string and has to operation defined, to ensure it is completely useless.
%}

INSTRUCTION help.new STR -> help.type
%{
	auto rs = ARGV_VALUE(0,string);
	auto s = RAW_STRING(rs);
	SVM_Value_String p = ::svm_plugin_get_option(svm,CONST_PEP(help,prefix));
	if(not ::svm_value_state_is_null(svm,p))
	{
		auto rp = ::svm_value_string_get(svm,p);
		s = RAW_STRING(rp)+s;
	}
	return NEW_PLUGIN(help,type,new type_type { s });
%}
help:
%{
This instruction creates an instance of the useless type.
The value is passed as parameter of this instruction.
.P
If the prefix is defined, it is added directly within the value of the useless type.
.P
This instruction raises no interruption.
%}

Générez à nouveau l'extension et rouvrez la page de manuel. Les objets de l'extension sont enfin documentés.

Chaque objet peut recevoir une section help suivie d'une chaine entre double-quote lorsque l'aide tient sur une ligne ou d'un bloc si plusieurs lignes sont nécessaires. Dans les deux cas, le contenu de l'aide est en groff.

Notez que les dépendances aussi peuvent être documentées en ajoutant une section help après chaque objet dont dépend l'extension, potentiellement pour indiquer pourquoi cette dépendance existe.

Conclusion

Vous venez de voir comment générer l'aide d'une extension.

Le générateur d'extension offre des facilités pour écrire la page de manuel des extensions, en donnant à la fois une vision d'ensemble, une vue précise de chaque objet et des exemples de code.

Souvent, une aide bien construite et exhaustive permet aux utilisateurs d'adopter une extension plus facilement, ce qui peut participer à sa popularité.