Skip to content

Commit 436e06e

Browse files
committed
Remove hidden global variable and procedure Register
The hidden global variable caused several hooks to be attached to the wrong plug-in when loading multiple Ada plug-ins. In order to provide the plug-in pointer to callbacks, the pointer is put inside a record that is allocated on the heap. This record will be deallocated by WeeChat when the hook is removed (when the plug-in is unloaded). Procedure Register has been removed because WeeChat uses the exported weechat_* symbols to display certain metadata of the plug-in. Even though the plug-in metadata is part of the plug-in data structure. Plug-ins must now copy some boilerplate code to export this metadata. Signed-off-by: onox <denkpadje@gmail.com>
1 parent 67b5c22 commit 436e06e

File tree

5 files changed

+305
-255
lines changed

5 files changed

+305
-255
lines changed

README.md

+87-15
Original file line numberDiff line numberDiff line change
@@ -43,30 +43,79 @@ for a language like Ada:
4343
## Usage
4444

4545
```ada
46-
package Plugin
46+
package Plugin_My_Plugin_Name
4747
pragma Elaborate_Body;
48-
end Plugin;
48+
end Plugin_My_Plugin_Name;
4949
```
5050

51+
Because your plug-in is build as a stand-alone library, the Ada package
52+
of your plug-in should have a unique name in order to avoid unexpected
53+
behavior due to symbol name collisions when you load multiple Ada plug-ins.
54+
55+
You must export several C strings and two functions, called when the plug-in
56+
is loaded and unloaded:
57+
5158
```ada
59+
with System;
60+
61+
with Interfaces.C;
62+
5263
with WeeChat;
5364
54-
package body Plugin is
65+
package body Plugin_My_Plugin_Name is
66+
5567
use WeeChat;
5668
57-
procedure Plugin_Initialize is
69+
procedure Plugin_Initialize (Plugin : Plugin_Ptr) is
5870
begin
59-
Print ("Hello world from Ada");
71+
Print (Plugin, "Hello world from Ada");
6072
6173
-- Call the various On_* subprograms here to set-up hooks
6274
end Plugin_Initialize;
6375
64-
procedure Plugin_Finalize is null;
65-
begin
66-
WeeChat.Register
67-
("ada", "Ada Lovelace", "Plug-in written in Ada 2012", "1.0", "Apache-2.0",
68-
Plugin_Initialize'Access, Plugin_Finalize'Access);
69-
end Plugin;
76+
procedure Plugin_Finalize (Plugin : Plugin_Ptr) is null;
77+
78+
Plugin_Name : constant C_String := "mypluginname" & L1.NUL
79+
with Export, Convention => C, External_Name => "weechat_plugin_name";
80+
81+
Plugin_Author : constant C_String := "Ada Lovelace" & L1.NUL
82+
with Export, Convention => C, External_Name => "weechat_plugin_author";
83+
84+
Plugin_Description : constant C_String := "My WeeChat plug-in written in Ada 2012" & L1.NUL
85+
with Export, Convention => C, External_Name => "weechat_plugin_description";
86+
87+
Plugin_Version : constant C_String := "1.0" & L1.NUL
88+
with Export, Convention => C, External_Name => "weechat_plugin_version";
89+
90+
Plugin_License : constant C_String := "Apache-2.0" & L1.NUL
91+
with Export, Convention => C, External_Name => "weechat_plugin_license";
92+
93+
Plugin_API_Version : constant C_String := WeeChat.Plugin_API_Version
94+
with Export, Convention => C, External_Name => "weechat_plugin_api_version";
95+
96+
function Plugin_Init
97+
(Object : Plugin_Ptr;
98+
Argc : Interfaces.C.int;
99+
Argv : System.Address) return Callback_Result
100+
with Export, Convention => C, External_Name => "weechat_plugin_init";
101+
102+
function Plugin_End (Object : Plugin_Ptr) return Callback_Result
103+
with Export, Convention => C, External_Name => "weechat_plugin_end";
104+
105+
function Plugin_Init
106+
(Object : Plugin_Ptr;
107+
Argc : Interfaces.C.int;
108+
Argv : System.Address) return Callback_Result is
109+
begin
110+
return Plugin_Init (Object, Plugin_Initialize'Access);
111+
end Plugin_Init;
112+
113+
function Plugin_End (Object : Plugin_Ptr) return Callback_Result is
114+
begin
115+
return Plugin_End (Object, Plugin_Finalize'Access);
116+
end Plugin_End;
117+
118+
end Plugin_My_Plugin_Name;
70119
```
71120

72121
You must be careful not to spawn any tasks that cannot be terminated. For
@@ -83,8 +132,8 @@ loop
83132
end loop;
84133
```
85134

86-
You should add this code to an exception handler in `Plugin_Initialize` and
87-
to `Plugin_Finalize`.
135+
If you create any tasks, you should add this code to an exception handler
136+
in `Plugin_Initialize` and `Plugin_Finalize`.
88137

89138
## Dependencies
90139

@@ -131,17 +180,38 @@ with "weechat";
131180
You must make sure to build the plug-in as a Stand-Alone Library:
132181

133182
```ada
134-
for Library_Version use "my-weechat-plugin.so";
135-
for Library_Interface use ("plugin");
183+
library project WeeChat_My_Plugin is
184+
185+
for Library_Name use "weechat_my_plugin";
186+
for Library_Version use "ada-my-plugin.so";
187+
for Library_Kind use "relocatable";
188+
189+
for Library_Interface use ("plugin_my_plugin_name");
190+
for Library_Standalone use "encapsulated";
191+
192+
end WeeChat_My_Plugin;
136193
```
137194

195+
You can copy ada-my-plugin.so to ~/.weechat/plugins/.
196+
197+
`Library_Standalone` should either be "standard" or "encapsulated".
198+
"encapsulated" will put the GNAT RTS inside your library and will force any
199+
third-party Ada libraries that you import to be compiled as "static-pic" instead
200+
of "dynamic" or "relocatable". "standard" does not have these restrictions,
201+
but reloading or unloading your plug-in may segfault WeeChat if there is
202+
another plug-in that uses "standard" as well. Therefore the safest option
203+
is to choose "encapsulated" if you can live with the restrictions.
204+
138205
If you need to link to some specific library, you can use `Library_Options`.
139206
For example:
140207

141208
```ada
142209
for Library_Options use ("-lcanberra");
143210
```
144211

212+
For a complete example see [weechat-canberra][url-weechat-canberra] or
213+
[weechat-emoji][url-weechat-emoji].
214+
145215
## Contributing
146216

147217
Read the [contributing guidelines][url-contributing] if you want to add
@@ -158,3 +228,5 @@ refers to this license:
158228
[url-apache]: https://opensource.org/licenses/Apache-2.0
159229
[url-contributing]: /CONTRIBUTING.md
160230
[url-weechat]: https://weechat.org/
231+
[url-weechat-canberra]: https://github.com/onox/weechat-canberra
232+
[url-weechat-emoji]: https://github.com/onox/weechat-emoji

0 commit comments

Comments
 (0)