Plugins are use to implement new functions in GO to be use by goweb. The module need to be implemented as a main module using goweb/vm module. The Makefile to compile the plugin can be:
example: *.go
go build -buildmode=plugin
install example.so /usr/local/lib
test:
go test -v
To use the module you can modify the toml configuation file as in:
[description]
plugin = [ "example"]
[example]
file="/usr/local/lib/example.so"
init="Register_function"
The init parameter define the function that we be use to define all functions:
package main
import (
"goweb/vm"
"log"
)
func Register_function(v *vm.Vm) {
v.Listfunc["example"] = goweb_example
}
func goweb_plugin_example(v *vm.Vm, nbelem int) error {
// scan arguments
var file string
var errid string
var err error
generr := false
for i := 0; i < nbelem; i++ {
d := v.Stack[v.Sp-(nbelem-i)]
if d.Data_type == vm.Type_id {
v, _, err := vm.Get_id(v, d.Id)
if err != nil {
return fmt.Errorf("plugin::example : id is not defined: %!s(MISSING)", d.Id)
}
d = v
} else if d.Data_type == vm.Type_nargs {
nargs := d.Nargs
i++
next := v.Stack[v.Sp-(nbelem-i)]
switch nargs {
case "error":
if next.Data_type != vm.Type_id {
return fmt.Errorf("plugin::example : invalid id for parameter %!s(MISSING): %!s(MISSING)", nargs, vm.Type_text[next.Data_type])
}
errid = next.Id
vm.New_id(v, errid, vm.Data_value{})
case "generr":
generr = true
default:
return fmt.Errorf("plugin::example : id is not defined: %!s(MISSING)", d.Id)
}
} else {
if file != "" {
return fmt.Errorf("plugin::example : only 1 file can be use")
}
file, err = vm.Get_sval(v, d)
if err != nil {
return fmt.Errorf("plugin::example : parameter 1 can't be a string")
}
}
}
// remove argument from stack
v.Sp -= nbelem
if generr {
err := vm.Errorid(v, errid, "an error has been requested: id=%!s(MISSING)", errid)
if err != nil {
return err
}
}
// Push element on stack
data_value := vm.Data_value{
Data_type: vm.Type_string,
Sval: "example",
}
v.Stack[v.Sp] = data_value
v.Sp++
return nil
title: “PLUGINS” author: “Pierre Laplante laplante@plcb.ca” date: “2023-07-13” version: “1.0” section: “1g”
Plugins are used to implement new functions in Go that can be executed within goweb.
A plugin must be implemented as a main module using the goweb/vm
package.
example: *.go
go build -buildmode=plugin
install example.so /usr/local/lib
test:
go test -v
To use a plugin, update the TOML configuration file:
[description]
plugin = [ "example" ]
[example]
file="/usr/local/lib/example.so"
init="Register_function"
The init
parameter specifies the function that will be invoked to register all plugin-defined functions.
package main
import (
"goweb/vm"
"log"
)
func Register_function(v *vm.Vm) {
v.Listfunc["example"] = goweb_example
}
func goweb_plugin_example(v *vm.Vm, nbelem int) error {
// scan arguments
var file string
var errid string
var err error
generr := false
for i := 0; i < nbelem; i++ {
d := v.Stack[v.Sp-(nbelem-i)]
if d.Data_type == vm.Type_id {
v, _, err := vm.Get_id(v, d.Id)
if err != nil {
return fmt.Errorf("plugin::example : id is not defined: %!s(MISSING)", d.Id)
}
d = v
} else if d.Data_type == vm.Type_nargs {
nargs := d.Nargs
i++
next := v.Stack[v.Sp-(nbelem-i)]
switch nargs {
case "error":
if next.Data_type != vm.Type_id {
return fmt.Errorf("plugin::example : invalid id for parameter %!s(MISSING): %!s(MISSING)", nargs, vm.Type_text[next.Data_type])
}
errid = next.Id
vm.New_id(v, errid, vm.Data_value{})
case "generr":
generr = true
default:
return fmt.Errorf("plugin::example : invalid parameter: %!s(MISSING)", d.Id)
}
} else {
if file != "" {
return fmt.Errorf("plugin::example : only one file can be specified")
}
file, err = vm.Get_sval(v, d)
if err != nil {
return fmt.Errorf("plugin::example : parameter must be a string")
}
}
}
// remove arguments from stack
v.Sp -= nbelem
if generr {
err := vm.Errorid(v, errid, "an error has been requested: id=%!s(MISSING)", errid)
if err != nil {
return err
}
}
// push element on stack
data_value := vm.Data_value{
Data_type: vm.Type_string,
Sval: "example",
}
v.Stack[v.Sp] = data_value
v.Sp++
return nil
}